最近在写一款软件,其中一个功能就是透视,在网上搜索了很久,翻阅了很多资料。第一份资料呈现给我的就是【猴健居士】写的一篇关于【C# 图片*变换 任意扭曲】,我很想去实现那种效果,只是才疏学浅,无法明白其思路,即使有贴出来了代码,我也没有做到,很惭愧。
而网上其他的方式多半是与【OpenCV】结合,这种很简单,却让我头大,这对于我来说无意是接触一种新的语言,奈何时间不会那么充裕。
最终我还是决定,以C#自身的情况,来实现这种效果,我自己是无法办到的,就想到了第一次看到的那个文章,的确是用C#语言写的。只是我无法还原,于是找到了这个朋友,希望他可以帮忙。
那朋友知道的来意后,帮了我,点出了我的问题,并告诉了这段代码的存在什么问题。我在得知后,很高兴,也很感谢,先能实现再说,具体有什么问题,在实现后,应该会逐步克服。
现在贴出我在得到代码后的变动。
1、之前代码会有黑色背景,我改动过避免了这种情况,毕竟有些图片带着透明效果的
2、在循环中增加了continue,可以缩短图片的转换时间,对于有透明效果的图片很明显。
3、代码了用了重载和函数,增加了使用型
4、去掉了一部分代码,我不知道那些代码会达到什么效果,只是在代码中意义不大,暂时放弃了。
图片效果如下
我用一个类Perspective 来实现完成透视的效果,代码如下:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace ImageFile
{
/// <summary>
/// 透视
/// </summary>
public class Perspective
{
private int roundup(double a) { if (AafAbs(a - round(a)) < 1e-9) return round(a); else if ((int)a > a) return (int)a; else return (int)a + 1; }
private int rounddown(double a) { if (AafAbs(a - round(a)) < 1e-9) return round(a); else if ((int)a < a) return (int)a; else return (int)a - 1; }
private int round(double a) { return (int)(a + 0.5); }
private byte byterange(double a) { int b = round(a); if (b <= 0) return 0; else if (b >= 255) return 255; else return (byte)b; }
private double AafAbs(double a) { return (((a) < 0) ? (-(a)) : (a)); }
private double aaf_min(double a, double b) { if (a < b) return a; else return b; }
private double aaf_max(double a, double b) { if (a > b) return a; else return b; }
private AafPnt[] pixelgrid;
private AafPnt[] polyoverlap;
private AafPnt[] polysorted;
private AafPnt[] corners;
private int outstartx;
private int outstarty;
private int outwidth;
private int outheight;
private Bitmap prepImg;
private List<double> xDouList;
private List<double> yDouList;
int polyoverlapsize;
int polysortedsize;
int[] ja = new int[] { 1, 2, 3, 0 };
public Perspective() {
}
public Perspective(double[] xcorner, double[] ycorner)
{
xDouList = xcorner.ToList();
yDouList = ycorner.ToList();
}
public Perspective(Bitmap src,double[] xcorner, double[] ycorner)
{
prepImg = src;
xDouList = xcorner.ToList();
yDouList = ycorner.ToList();
}
public Bitmap CreateTransform()
{
return CreateTransform(prepImg);
}