该类是生成一个验证码的类,集合了网上大部分的C#关于GDI+的文章进行多次改进,现在已经形成了可在生产环节中使用的验证码。

该验证码加入了背景噪点,背景噪点曲线和直线,背景噪点文字以及扭曲,调暗,模糊等。完全可以实现防识别。

对安全性要求比较高的网站尤其适用。

同时该类还还收集了GDI+的图像处理方面的函数,包括雾化,扭曲,水波,锐化,高斯模糊,画直线,画曲线生成随机颜色,缩放图片,柔化图片,图片黑白化,增加曝光度,RGB滤镜,绘制圆角等功能。

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Drawing.Imaging; /**********************
* 验证码生成类
* 作者:李飞麟
* URL:http://www.xuehuwang.com
* Email:lifei6671@163.com
*
* *********************/
namespace NS.DrawValidationCode
{
#region 验证码生成类
/// <summary>
/// 验证码生成类
/// </summary>
public class DrawValidationCode
{
#region 定义和初始化配置字段
//用户存取验证码字符串
private string validationCode = String.Empty;
/// <summary>
/// 获取系统生成的随机验证码
/// </summary>
public String ValidationCode
{
get { return validationCode; }
}
private Int32 validationCodeCount = ;
/// <summary>
/// 获取和设置验证码字符串的长度
/// </summary>
public Int32 ValidationCodeCount
{
get { return validationCodeCount; }
set { validationCodeCount = value; }
}
Graphics dc = null;
private int bgWidth = ;
/// <summary>
/// 验证码的宽度,默认为80
/// </summary>
public Int32 Width
{
get { return bgWidth; }
set { bgWidth = value; }
} private int bgHeight = ;
/// <summary>
/// 验证码的高度,默认为40
/// </summary>
public Int32 Height
{
get { return bgHeight; }
set { bgHeight = value; }
}
/* private string[] fontFace = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" };
/// <summary>
/// 验证码字体列表,默认为{ "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" }
/// </summary>
public String[] FontFace
{
get { return fontFace; }
set { fontFace = value; }
}*/ private int fontMinSize = ;
/// <summary>
/// 验证码字体的最小值,默认为15,建议不小于15像素
/// </summary>
public Int32 FontMinSize
{
get { return fontMinSize; }
set { fontMinSize = value; }
}
private Int32 fontMaxSize = ;
/// <summary>
/// 验证码字体的最大值,默认为20
/// </summary>
public Int32 FontMaxSize
{
get { return fontMaxSize; }
set { fontMaxSize = value; }
}
private Color[] fontColor = { };
/// <summary>
/// 验证码字体的颜色,默认为系统自动生成字体颜色
/// </summary>
public Color[] FontColor
{
get { return fontColor; }
set { fontColor = value; }
}
private Color backColor = Color.FromArgb(, , );
/// <summary>
/// 验证码的背景色,默认为Color.FromArgb(243, 251, 254)
/// </summary>
public Color BackgroundColor
{
get { return backColor; }
set { backColor = value; }
}
private Int32 bezierCount = ;
/// <summary>
/// 贝塞尔曲线的条数,默认为3条
/// </summary>
public Int32 BezierCount
{
get { return bezierCount; }
set { bezierCount = value; }
}
private Int32 lineCount = ;
/// <summary>
/// 直线条数,默认为3条
/// </summary>
public Int32 LineCount
{
get { return lineCount; }
set { lineCount = value; }
}
Random random; private String charCollection = "2,3,4,5,6,7,8,9,a,s,d,f,g,h,z,c,v,b,n,m,k,q,w,e,r,t,y,u,p,A,S,D,F,G,H,Z,C,V,B,N,M,K,Q,W,E,R,T,Y,U,P"; //定义验证码字符及出现频次 ,避免出现0 o j i l 1 x;
/// <summary>
/// 随机字符串列表,请使用英文状态下的逗号分隔。
/// </summary>
public String CharCollection
{
get { return charCollection; }
set { charCollection = value; }
}
private Int32 intCount = ;
/// <summary>
/// 验证码字符串个数,默认为4个字符
/// </summary>
public Int32 IntCount
{
get { return intCount; }
set { intCount = value; }
}
private Boolean isPixel = true;
/// <summary>
/// 是否添加噪点,默认添加,噪点颜色为系统随机生成。
/// </summary>
public Boolean IsPixel
{
get { return isPixel; }
set { isPixel = value; }
}
private Boolean isRandString = true;
/// <summary>
/// 是否添加随机噪点字符串,默认添加
/// </summary>
public Boolean IsRandString
{
get { return isRandString; }
set { isRandString = value; }
}
/// <summary>
/// 随机背景字符串的个数
/// </summary>
public Int32 RandomStringCount
{
get;
set;
}
private Int32 randomStringFontSize = ;
/// <summary>
/// 随机背景字符串的大小
/// </summary>
public Int32 RandomStringFontSize
{
get { return randomStringFontSize; }
set { randomStringFontSize = value; }
}
/// <summary>
/// 是否对图片进行扭曲
/// </summary>
public Boolean IsTwist
{
get;
set;
}
/// <summary>
/// 边框样式
/// </summary>
public enum BorderStyle
{
/// <summary>
/// 无边框
/// </summary>
None,
/// <summary>
/// 矩形边框
/// </summary>
Rectangle,
/// <summary>
/// 圆角边框
/// </summary>
RoundRectangle
}
private Int32 rotationAngle = ;
/// <summary>
/// 验证码字符串随机转动的角度的最大值
/// </summary>
public Int32 RotationAngle
{
get { return rotationAngle; }
set { rotationAngle = value; }
}
/// <summary>
/// 设置或获取边框样式
/// </summary>
public BorderStyle Border
{
get;
set;
}
private Point[] strPoint = null; private Double gaussianDeviation = ;
/// <summary>
/// 对验证码图片进行高斯模糊的阀值,如果设置为0,则不对图片进行高斯模糊,该设置可能会对图片处理的性能有较大影响
/// </summary>
public Double GaussianDeviation
{
get { return gaussianDeviation; }
set { gaussianDeviation = value; }
}
private Int32 brightnessValue = ;
/// <summary>
/// 对图片进行暗度和亮度的调整,如果该值为0,则不调整。该设置会对图片处理性能有较大影响
/// </summary>
public Int32 BrightnessValue
{
get { return brightnessValue; }
set { brightnessValue = value; }
}
#endregion
/// <summary>
/// 构造函数,用于初始化常用变量
/// </summary>
public DrawValidationCode()
{
random = new Random(Guid.NewGuid().GetHashCode());
strPoint = new Point[validationCodeCount + ];
if (gaussianDeviation < ) gaussianDeviation = ;
} /// <summary>
/// 生成验证码
/// </summary>
/// <param name="target">用于存储图片的一般字节序列</param>
public void CreateImage(Stream target)
{
Bitmap bit = new Bitmap(bgWidth + , bgHeight + );
//写字符串
dc = Graphics.FromImage(bit);
dc.SmoothingMode = SmoothingMode.HighQuality;
dc.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; ;
dc.InterpolationMode = InterpolationMode.HighQualityBilinear;
dc.CompositingQuality = CompositingQuality.HighQuality; dc.Clear(Color.White);
dc.DrawImageUnscaled(DrawBackground(), , );
dc.DrawImageUnscaled(DrawRandomString(), , );
//对图片文字进行扭曲
bit = AdjustRippleEffect(bit, );
//对图片进行高斯模糊
if (gaussianDeviation > )
{
Gaussian gau = new Gaussian();
bit = gau.FilterProcessImage(gaussianDeviation, bit);
}
//进行暗度和亮度处理
if (brightnessValue != )
{
//对图片进行调暗处理
bit = AdjustBrightness(bit, brightnessValue);
}
bit.Save(target, ImageFormat.Gif);
//brush.Dispose();
bit.Dispose();
dc.Dispose();
} #region 画验证码背景,例如,增加早点,添加曲线和直线等
/// <summary>
/// 画验证码背景,例如,增加早点,添加曲线和直线等
/// </summary>
/// <returns></returns>
private Bitmap DrawBackground()
{
Bitmap bit = new Bitmap(bgWidth + , bgHeight + );
Graphics g = Graphics.FromImage(bit);
g.SmoothingMode = SmoothingMode.HighQuality; g.Clear(Color.White);
Rectangle rectangle = new Rectangle(, , bgWidth, bgHeight);
Brush brush = new SolidBrush(backColor);
g.FillRectangle(brush, rectangle); //画噪点
if (isPixel)
{
g.DrawImageUnscaled(DrawRandomPixel(), , );
}
g.DrawImageUnscaled(DrawRandBgString(), , ); //画曲线
g.DrawImageUnscaled(DrawRandomBezier(bezierCount), , );
//画直线
g.DrawImageUnscaled(DrawRandomLine(lineCount), , ); //dc.DrawImageUnscaled(DrawStringline(), 0, 0);
if (Border == BorderStyle.Rectangle)
{
//绘制边框
g.DrawRectangle(new Pen(Color.FromArgb(, , )), , , bgWidth, bgHeight);
}
else if (Border == BorderStyle.RoundRectangle)
{
//画圆角
DrawRoundRectangle(g, rectangle, Color.FromArgb(, , ), , );
} return bit; }
#endregion #region 画正弦曲线
private Bitmap DrawTwist(Bitmap bmp, Int32 tWidth, Int32 tHeight, float angle, Color color)
{
//为了方便查看效果,在这里我定义了一个常量。
//它在定义数组的长度和for循环中都要用到。
int size = bgWidth; double[] x = new double[size];
Bitmap b = new Bitmap(bmp.Width, bmp.Height);
b.MakeTransparent();
Graphics graphics = Graphics.FromImage(b);
Pen pen = new Pen(color); //画正弦曲线的横轴间距参数。建议所用的值应该是 正数且是2的倍数。
//在这里采用2。
int val = ; float temp = 0.0f; //把画布下移100。为什么要这样做,只要你把这一句给注释掉,运行一下代码,
//你就会明白是为什么?
graphics.TranslateTransform(, );
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
for (int i = ; i < size; i++)
{
//改变tWidth,实现正弦曲线宽度的变化。
//改tHeight,实现正弦曲线高度的变化。
x[i] = Math.Sin( * Math.PI * i / tWidth) * tHeight; graphics.DrawLine(pen, i * val, temp, i * val + val / , (float)x[i]);
temp = (float)x[i];
}
graphics.RotateTransform(, MatrixOrder.Prepend); //旋转图片
// b = KiRotate(b, angle, Color.Transparent);
return b;
}
#endregion #region 正弦曲线Wave扭曲图片
/// <summary>
/// 正弦曲线Wave扭曲图片
/// </summary>
/// <param name="srcBmp">图片路径</param>
/// <param name="bXDir">如果扭曲则选择为True</param>
/// <param name="dMultValue">波形的幅度倍数,越大扭曲的程度越高,一般为3</param>
/// <param name="dPhase">波形的起始相位,取值区间[0-2*PI)</param>
/// <returns></returns>
public Bitmap TwistImage(Bitmap srcBmp, bool bXDir, double dMultValue, double dPhase)
{
System.Drawing.Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height);
double PI2 = 6.283185307179586476925286766559;
// 将位图背景填充为白色
System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(destBmp);
graph.FillRectangle(new SolidBrush(System.Drawing.Color.White), , , destBmp.Width, destBmp.Height);
graph.Dispose(); double dBaseAxisLen = bXDir ? (double)destBmp.Height : (double)destBmp.Width; for (int i = ; i < destBmp.Width; i++)
{
for (int j = ; j < destBmp.Height; j++)
{
double dx = ;
dx = bXDir ? (PI2 * (double)j) / dBaseAxisLen : (PI2 * (double)i) / dBaseAxisLen;
dx += dPhase;
double dy = Math.Sin(dx); // 取得当前点的颜色
int nOldX = , nOldY = ;
nOldX = bXDir ? i + (int)(dy * dMultValue) : i;
nOldY = bXDir ? j : j + (int)(dy * dMultValue); System.Drawing.Color color = srcBmp.GetPixel(i, j);
if (nOldX >= && nOldX < destBmp.Width
&& nOldY >= && nOldY < destBmp.Height)
{
destBmp.SetPixel(nOldX, nOldY, color);
}
}
}
return destBmp;
}
#endregion #region 图片任意角度旋转
/// <summary>
/// 图片任意角度旋转
/// </summary>
/// <param name="bmp">原始图Bitmap</param>
/// <param name="angle">旋转角度</param>
/// <param name="bkColor">背景色</param>
/// <returns>输出Bitmap</returns>
public static Bitmap KiRotate(Bitmap bmp, float angle, Color bkColor)
{
int w = bmp.Width;
int h = bmp.Height; PixelFormat pf; if (bkColor == Color.Transparent)
{
pf = PixelFormat.Format32bppArgb;
}
else
{
pf = bmp.PixelFormat;
} Bitmap tmp = new Bitmap(w, h, pf);
Graphics g = Graphics.FromImage(tmp);
g.Clear(bkColor);
g.DrawImageUnscaled(bmp, , );
g.Dispose(); GraphicsPath path = new GraphicsPath();
path.AddRectangle(new RectangleF(0f, 0f, w, h));
Matrix mtrx = new Matrix();
mtrx.Rotate(angle);
RectangleF rct = path.GetBounds(mtrx); Bitmap dst = new Bitmap((int)rct.Width, (int)rct.Height, pf);
g = Graphics.FromImage(dst);
g.Clear(bkColor);
g.TranslateTransform(-rct.X, -rct.Y);
g.RotateTransform(angle);
g.InterpolationMode = InterpolationMode.HighQualityBilinear;
g.DrawImageUnscaled(tmp, , );
g.Dispose();
tmp.Dispose(); return dst;
}
#endregion #region 随机生成贝塞尔曲线
/// <summary>
/// 随机生成贝塞尔曲线
/// </summary>
/// <param name="bmp">一个图片的实例</param>
/// <param name="lineNum">线条数量</param>
/// <returns></returns>
public Bitmap DrawRandomBezier(Int32 lineNum)
{
Bitmap b = new Bitmap(bgWidth, bgHeight);
b.MakeTransparent();
Graphics g = Graphics.FromImage(b);
g.Clear(Color.Transparent);
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality; GraphicsPath gPath1 = new GraphicsPath();
Int32 lineRandNum = random.Next(lineNum); for (int i = ; i < (lineNum - lineRandNum); i++)
{
Pen p = new Pen(GetRandomDeepColor());
Point[] point = {
new Point(random.Next(, (b.Width / )), random.Next(, (b.Height))),
new Point(random.Next((b.Width / ) * , (b.Width / ) * ), random.Next(, (b.Height))),
new Point(random.Next((b.Width / ) * , (b.Width / ) * ), random.Next(, (b.Height))),
new Point(random.Next((b.Width / ) * , b.Width), random.Next(, (b.Height)))
}; gPath1.AddBeziers(point);
g.DrawPath(p, gPath1);
p.Dispose();
}
for (int i = ; i < lineRandNum; i++)
{
Pen p = new Pen(GetRandomDeepColor());
Point[] point = {
new Point(random.Next(, b.Width), random.Next(, b.Height)),
new Point(random.Next((b.Width / ) * , b.Width), random.Next(, b.Height)),
new Point(random.Next((b.Width / ) * , b.Width), random.Next(, b.Height)),
new Point(random.Next(, b.Width), random.Next(, b.Height))
};
gPath1.AddBeziers(point);
g.DrawPath(p, gPath1);
p.Dispose();
}
return b;
}
#endregion #region 画直线
/// <summary>
/// 画直线
/// </summary>
/// <param name="bmp">一个bmp实例</param>
/// <param name="lineNum">线条个数</param>
/// <returns></returns>
public Bitmap DrawRandomLine(Int32 lineNum)
{
if (lineNum < ) throw new ArgumentNullException("参数bmp为空!");
Bitmap b = new Bitmap(bgWidth, bgHeight);
b.MakeTransparent();
Graphics g = Graphics.FromImage(b);
g.Clear(Color.Transparent);
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.SmoothingMode = SmoothingMode.HighQuality;
for (int i = ; i < lineNum; i++)
{
Pen p = new Pen(GetRandomDeepColor());
Point pt1 = new Point(random.Next(, (b.Width / ) * ), random.Next(b.Height));
Point pt2 = new Point(random.Next((b.Width / ) * , b.Width), random.Next(b.Height));
g.DrawLine(p, pt1, pt2);
p.Dispose();
} return b;
}
#endregion #region 画随机噪点
/// <summary>
/// 画随机噪点
/// </summary>
/// <param name="pixNum">噪点的百分比</param>
/// <returns></returns>
public Bitmap DrawRandomPixel(Int32 pixNum)
{
Bitmap b = new Bitmap(bgWidth, bgHeight);
b.MakeTransparent();
Graphics graph = Graphics.FromImage(b);
graph.SmoothingMode = SmoothingMode.HighQuality;
graph.InterpolationMode = InterpolationMode.HighQualityBilinear; //画噪点
for (int i = ; i < (bgHeight * bgWidth) / pixNum; i++)
{
int x = random.Next(b.Width);
int y = random.Next(b.Height);
b.SetPixel(x, y, GetRandomDeepColor());
//下移坐标重新画点
if ((x + ) < b.Width && (y + ) < b.Height)
{
//画图片的前景噪音点
graph.DrawRectangle(new Pen(Color.Silver), random.Next(b.Width), random.Next(b.Height), , );
} } return b;
}
#endregion #region 画随机字符串中间连线
/// <summary>
/// 画随机字符串中间连线
/// </summary>
/// <returns></returns>
private Bitmap DrawStringline()
{
Bitmap b = new Bitmap(bgWidth, bgHeight);
b.MakeTransparent();
Graphics g = Graphics.FromImage(b);
g.SmoothingMode = SmoothingMode.AntiAlias; Point[] p = new Point[validationCodeCount];
for (int i = ; i < validationCodeCount; i++)
{
p[i] = strPoint[i];
//throw new Exception(strPoint.Length.ToString());
}
// g.DrawBezier(new Pen(GetRandomDeepColor()), strPoint);
//g.DrawClosedCurve(new Pen(GetRandomDeepColor()), strPoint);
g.DrawCurve(new Pen(GetRandomDeepColor(), ), strPoint); return b;
}
#endregion #region 写入验证码的字符串
/// <summary>
/// 写入验证码的字符串
/// </summary>
private Bitmap DrawRandomString()
{
if (fontMaxSize >= (bgHeight / ) * ) throw new ArgumentException("字体最大值参数FontMaxSize与验证码高度相近,这会导致描绘验证码字符串时出错,请重新设置参数!");
Bitmap b = new Bitmap(bgWidth, bgHeight);
b.MakeTransparent();
Graphics g = Graphics.FromImage(b); g.Clear(Color.Transparent);
g.PixelOffsetMode = PixelOffsetMode.Half;
g.SmoothingMode = SmoothingMode.HighQuality;
g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
g.InterpolationMode = InterpolationMode.HighQualityBilinear; char[] chars = GetRandomString(validationCodeCount).ToCharArray();//拆散字符串成单字符数组
validationCode = chars.ToString(); //设置字体显示格式
StringFormat format = new StringFormat(StringFormatFlags.NoClip);
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
FontFamily f = new FontFamily(GenericFontFamilies.Monospace); Int32 charNum = chars.Length; Point sPoint = new Point();
Int32 fontSize = ;
for (int i = ; i < validationCodeCount; i++)
{
int findex = random.Next();
//定义字体
Font textFont = new Font(f, random.Next(fontMinSize, fontMaxSize), FontStyle.Bold);
//定义画刷,用于写字符串
//Brush brush = new SolidBrush(GetRandomDeepColor());
Int32 textFontSize = Convert.ToInt32(textFont.Size);
fontSize = textFontSize;
Point point = new Point(random.Next((bgWidth / charNum) * i + , (bgWidth / charNum) * (i + )), random.Next(bgHeight / + textFontSize / , bgHeight - textFontSize / )); //如果当前字符X坐标小于字体的二分之一大小
if (point.X < textFontSize / )
{
point.X = point.X + textFontSize / ;
}
//防止文字叠加
if (i > && (point.X - sPoint.X < (textFontSize / + textFontSize / )))
{
point.X = point.X + textFontSize;
}
//如果当前字符X坐标大于图片宽度,就减去字体的宽度
if (point.X > (bgWidth - textFontSize / ))
{
point.X = bgWidth - textFontSize / ;
} sPoint = point; float angle = random.Next(-rotationAngle, rotationAngle);//转动的度数
g.TranslateTransform(point.X, point.Y);//移动光标到指定位置
g.RotateTransform(angle); //设置渐变画刷
Rectangle myretang = new Rectangle(, , Convert.ToInt32(textFont.Size), Convert.ToInt32(textFont.Size));
Color c = GetRandomDeepColor();
LinearGradientBrush mybrush2 = new LinearGradientBrush(myretang, c, GetLightColor(c, ), random.Next()); g.DrawString(chars[i].ToString(), textFont, mybrush2, , , format); g.RotateTransform(-angle);//转回去
g.TranslateTransform(-point.X, -point.Y);//移动光标到指定位置,每个字符紧凑显示,避免被软件识别 strPoint[i] = point; textFont.Dispose();
mybrush2.Dispose();
}
return b;
}
#endregion #region 画干扰背景文字
/// <summary>
/// 画背景干扰文字
/// </summary>
/// <returns></returns>
private Bitmap DrawRandBgString()
{
Bitmap b = new Bitmap(bgWidth, bgHeight);
String[] randStr = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
b.MakeTransparent();
Graphics g = Graphics.FromImage(b); g.Clear(Color.Transparent);
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.SmoothingMode = SmoothingMode.HighQuality;
g.TextRenderingHint = TextRenderingHint.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBilinear; //设置字体显示格式
StringFormat format = new StringFormat(StringFormatFlags.NoClip);
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center; FontFamily f = new FontFamily(GenericFontFamilies.Serif);
Font textFont = new Font(f, randomStringFontSize, FontStyle.Underline); int randAngle = ; //随机转动角度 for (int i = ; i < RandomStringCount; i++)
{ Brush brush = new System.Drawing.SolidBrush(GetRandomLightColor());
Point pot = new Point(random.Next(, bgWidth - ), random.Next(, bgHeight - ));
//随机转动的度数
float angle = random.Next(-randAngle, randAngle); //转动画布
g.RotateTransform(angle);
g.DrawString(randStr[random.Next(randStr.Length)], textFont, brush, pot, format);
//转回去,为下一个字符做准备
g.RotateTransform(-angle);
//释放资源
brush.Dispose();
}
textFont.Dispose();
format.Dispose();
f.Dispose(); return b;
}
#endregion #region 生成随机字符串
/// <summary>
/// 生成随机字符串
/// </summary>
/// <returns></returns>
private string GetRandomString(Int32 textLength)
{
string[] randomArray = charCollection.Split(','); //将字符串生成数组
int arrayLength = randomArray.Length;
string randomString = "";
for (int i = ; i < textLength; i++)
{
randomString += randomArray[random.Next(, arrayLength)];
}
return randomString; //长度是textLength +1
}
#endregion #region 内部方法:绘制验证码背景
private void DrawBackground(HatchStyle hatchStyle)
{
//设置填充背景时用的笔刷
HatchBrush hBrush = new HatchBrush(hatchStyle, backColor); //填充背景图片
dc.FillRectangle(hBrush, , , this.bgWidth, this.bgHeight);
}
#endregion #region 根据指定长度,返回随机验证码
/// <summary>
/// 根据指定长度,返回随机验证码
/// </summary>
/// <param >制定长度</param>
/// <returns>随即验证码</returns>
public string Next(int length)
{
this.validationCode = GetRandomCode(length);
return this.validationCode;
}
#endregion #region 内部方法:返回指定长度的随机验证码字符串
/// <summary>
/// 根据指定大小返回随机验证码
/// </summary>
/// <param >字符串长度</param>
/// <returns>随机字符串</returns>
private string GetRandomCode(int length)
{
StringBuilder sb = new StringBuilder(); for (int i = ; i < length; i++)
{
sb.Append(Char.ConvertFromUtf32(RandomAZ09()));
} return sb.ToString();
}
#endregion #region 内部方法:产生随机数和随机点 /// <summary>
/// 产生0-9A-Z的随机字符代码
/// </summary>
/// <returns>字符代码</returns>
private int RandomAZ09()
{
int result = ;
Random ram = new Random();
int i = ram.Next(); switch (i)
{
case :
result = ram.Next(, );
break;
case :
result = ram.Next(, );
break;
} return result;
} /// <summary>
/// 返回一个随机点,该随机点范围在验证码背景大小范围内
/// </summary>
/// <returns>Point对象</returns>
private Point RandomPoint()
{
Random ram = new Random();
Point point = new Point(ram.Next(this.bgWidth), ram.Next(this.bgHeight));
return point;
}
#endregion #region 随机生成颜色值
/// <summary>
/// 生成随机深颜色
/// </summary>
/// <returns></returns>
public Color GetRandomDeepColor()
{
int nRed, nGreen, nBlue; // nBlue,nRed nGreen 相差大一点 nGreen 小一些
//int high = 255;
int redLow = ;
int greenLow = ;
int blueLow = ;
nRed = random.Next(redLow);
nGreen = random.Next(greenLow);
nBlue = random.Next(blueLow);
Color color = Color.FromArgb(nRed, nGreen, nBlue);
return color;
} /// <summary>
/// 生成随机浅颜色
/// </summary>
/// <returns>randomColor</returns>
public Color GetRandomLightColor()
{
int nRed, nGreen, nBlue; //越大颜色越浅
int low = ; //色彩的下限
int high = ; //色彩的上限
nRed = random.Next(high) % (high - low) + low;
nGreen = random.Next(high) % (high - low) + low;
nBlue = random.Next(high) % (high - low) + low;
Color color = Color.FromArgb(nRed, nGreen, nBlue);
return color;
}
/// <summary>
/// 生成随机颜色值
/// </summary>
/// <returns></returns>
public Color GetRandomColor()
{
int nRed, nGreen, nBlue; //越大颜色越浅
int low = ; //色彩的下限
int high = ; //色彩的上限
nRed = random.Next(high) % (high - low) + low;
nGreen = random.Next(high) % (high - low) + low;
nBlue = random.Next(high) % (high - low) + low;
Color color = Color.FromArgb(nRed, nGreen, nBlue);
return color;
}
/// <summary>
/// 获取与当前颜色值相加后的颜色
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
public Color GetLightColor(Color c, Int32 value)
{
int nRed = c.R, nGreen = c.G, nBlue = c.B; //越大颜色越浅
if (nRed + value < && nRed + value > )
{
nRed = c.R + ;
}
if (nGreen + value < && nGreen + value > )
{
nGreen = c.G + ;
}
if (nBlue + value < && nBlue + value > )
{
nBlue = c.B + ;
}
Color color = Color.FromArgb(nRed, nGreen, nBlue);
return color;
}
#endregion #region 合并图片
/// <summary>
/// 合并图片
/// </summary>
/// <param name="maps"></param>
/// <returns></returns>
private Bitmap MergerImg(params Bitmap[] maps)
{
int i = maps.Length;
if (i == )
throw new Exception("图片数不能够为0");
//创建要显示的图片对象,根据参数的个数设置宽度
Bitmap backgroudImg = new Bitmap(i * , );
Graphics g = Graphics.FromImage(backgroudImg);
//清除画布,背景设置为白色
g.Clear(System.Drawing.Color.White);
for (int j = ; j < i; j++)
{
//g.DrawImage(maps[j], j * 11, 0, maps[j].Width, maps[j].Height);
g.DrawImageUnscaled(maps[j], , );
}
g.Dispose();
return backgroudImg;
}
#endregion #region 生成不重复的随机数,该函数会消耗大量系统资源
/// <summary>
/// 生成不重复的随机数,该函数会消耗大量系统资源
/// </summary>
/// <returns></returns>
private static int GetRandomSeed()
{
byte[] bytes = new byte[];
System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
rng.GetBytes(bytes);
return BitConverter.ToInt32(bytes, );
}
#endregion #region 缩放图片
/// <summary>
/// 缩放图片
/// </summary>
/// <param name="bmp">原始Bitmap</param>
/// <param name="newW">新的宽度</param>
/// <param name="newH">新的高度</param>
/// <param name="Mode">缩放质量</param>
/// <returns>处理以后的图片</returns>
public static Bitmap KiResizeImage(Bitmap bmp, int newW, int newH, InterpolationMode Mode)
{
try
{
Bitmap b = new Bitmap(newW, newH);
Graphics g = Graphics.FromImage(b);
// 插值算法的质量
g.InterpolationMode = Mode;
g.DrawImage(bmp, new Rectangle(, , newW, newH), new Rectangle(, , bmp.Width, bmp.Height), GraphicsUnit.Pixel);
g.Dispose();
return b;
}
catch
{
return null;
}
}
#endregion #region 绘制圆角矩形
/// <summary>
/// C# GDI+ 绘制圆角矩形
/// </summary>
/// <param name="g">Graphics 对象</param>
/// <param name="rectangle">Rectangle 对象,圆角矩形区域</param>
/// <param name="borderColor">边框颜色</param>
/// <param name="borderWidth">边框宽度</param>
/// <param name="r">圆角半径</param>
private static void DrawRoundRectangle(Graphics g, Rectangle rectangle, Color borderColor, float borderWidth, int r)
{
// 如要使边缘平滑,请取消下行的注释
g.SmoothingMode = SmoothingMode.HighQuality; // 由于边框也需要一定宽度,需要对矩形进行修正
//rectangle = new Rectangle(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
Pen p = new Pen(borderColor, borderWidth);
// 调用 getRoundRectangle 得到圆角矩形的路径,然后再进行绘制
g.DrawPath(p, getRoundRectangle(rectangle, r));
}
#endregion #region 根据普通矩形得到圆角矩形的路径
/// <summary>
/// 根据普通矩形得到圆角矩形的路径
/// </summary>
/// <param name="rectangle">原始矩形</param>
/// <param name="r">半径</param>
/// <returns>图形路径</returns>
private static GraphicsPath getRoundRectangle(Rectangle rectangle, int r)
{
int l = * r;
// 把圆角矩形分成八段直线、弧的组合,依次加到路径中
GraphicsPath gp = new GraphicsPath();
gp.AddLine(new Point(rectangle.X + r, rectangle.Y), new Point(rectangle.Right - r, rectangle.Y));
gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Y, l, l), 270F, 90F); gp.AddLine(new Point(rectangle.Right, rectangle.Y + r), new Point(rectangle.Right, rectangle.Bottom - r));
gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Bottom - l, l, l), 0F, 90F); gp.AddLine(new Point(rectangle.Right - r, rectangle.Bottom), new Point(rectangle.X + r, rectangle.Bottom));
gp.AddArc(new Rectangle(rectangle.X, rectangle.Bottom - l, l, l), 90F, 90F); gp.AddLine(new Point(rectangle.X, rectangle.Bottom - r), new Point(rectangle.X, rectangle.Y + r));
gp.AddArc(new Rectangle(rectangle.X, rectangle.Y, l, l), 180F, 90F);
return gp;
}
#endregion #region 柔化
///<summary>
/// 柔化
/// </summary>
/// <param name="b">原始图</param>
/// <returns>输出图</returns>
public static Bitmap KiBlur(Bitmap b)
{ if (b == null)
{
return null;
} int w = b.Width;
int h = b.Height; try
{ Bitmap bmpRtn = new Bitmap(w, h, PixelFormat.Format24bppRgb); BitmapData srcData = b.LockBits(new Rectangle(, , w, h), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData dstData = bmpRtn.LockBits(new Rectangle(, , w, h), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); unsafe
{
byte* pIn = (byte*)srcData.Scan0.ToPointer();
byte* pOut = (byte*)dstData.Scan0.ToPointer();
int stride = srcData.Stride;
byte* p; for (int y = ; y < h; y++)
{
for (int x = ; x < w; x++)
{
//取周围9点的值
if (x == || x == w - || y == || y == h - )
{
//不做
pOut[] = pIn[];
pOut[] = pIn[];
pOut[] = pIn[];
}
else
{
int r1, r2, r3, r4, r5, r6, r7, r8, r9;
int g1, g2, g3, g4, g5, g6, g7, g8, g9;
int b1, b2, b3, b4, b5, b6, b7, b8, b9; float vR, vG, vB; //左上
p = pIn - stride - ;
r1 = p[];
g1 = p[];
b1 = p[]; //正上
p = pIn - stride;
r2 = p[];
g2 = p[];
b2 = p[]; //右上
p = pIn - stride + ;
r3 = p[];
g3 = p[];
b3 = p[]; //左侧
p = pIn - ;
r4 = p[];
g4 = p[];
b4 = p[]; //右侧
p = pIn + ;
r5 = p[];
g5 = p[];
b5 = p[]; //右下
p = pIn + stride - ;
r6 = p[];
g6 = p[];
b6 = p[]; //正下
p = pIn + stride;
r7 = p[];
g7 = p[];
b7 = p[]; //右下
p = pIn + stride + ;
r8 = p[];
g8 = p[];
b8 = p[]; //自己
p = pIn;
r9 = p[];
g9 = p[];
b9 = p[]; vR = (float)(r1 + r2 + r3 + r4 + r5 + r6 + r7 + r8 + r9);
vG = (float)(g1 + g2 + g3 + g4 + g5 + g6 + g7 + g8 + g9);
vB = (float)(b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8 + b9); vR /= ;
vG /= ;
vB /= ; pOut[] = (byte)vB;
pOut[] = (byte)vG;
pOut[] = (byte)vR; } pIn += ;
pOut += ;
}// end of x pIn += srcData.Stride - w * ;
pOut += srcData.Stride - w * ;
} // end of y
} b.UnlockBits(srcData);
bmpRtn.UnlockBits(dstData); return bmpRtn;
}
catch
{
return null;
} } // end of KiBlur
#endregion #region 滤镜
/// <summary>
/// 红色滤镜
/// </summary>
/// <param name="bitmap">Bitmap</param>
/// <param name="threshold">阀值 -255~255</param>
/// <returns></returns>
public System.Drawing.Bitmap AdjustToRed(System.Drawing.Bitmap bitmap, int threshold)
{
for (int y = ; y < bitmap.Height; y++)
{
for (int x = ; x < bitmap.Width; x++)
{
// 取得每一個 pixel
var pixel = bitmap.GetPixel(x, y);
var pR = pixel.R + threshold;
pR = Math.Max(pR, );
pR = Math.Min(, pR);
// 將改過的 RGB 寫回
// 只寫入紅色的值 , G B 都放零
System.Drawing.Color newColor = System.Drawing.Color.FromArgb(pixel.A, pR, , );
bitmap.SetPixel(x, y, newColor);
}
}
// 回傳結果
return bitmap;
} /// <summary>
/// 绿色滤镜
/// </summary>
/// <param name="bitmap">一个图片实例</param>
/// <param name="threshold">阀值 -255~+255</param>
/// <returns></returns>
public System.Drawing.Bitmap AdjustToGreen(System.Drawing.Bitmap bitmap, int threshold)
{
for (int y = ; y < bitmap.Height; y++)
{
for (int x = ; x < bitmap.Width; x++)
{
// 取得每一個 pixel
var pixel = bitmap.GetPixel(x, y);
//判斷是否超過255 如果超過就是255
var pG = pixel.G + threshold;
//如果小於0就為0
if (pG > ) pG = ;
if (pG < ) pG = ;
// 將改過的 RGB 寫回
// 只寫入綠色的值 , R B 都放零
System.Drawing.Color newColor = System.Drawing.Color.FromArgb(pixel.A, , pG, );
bitmap.SetPixel(x, y, newColor);
}
}
// 回傳結果
return bitmap;
}
/// <summary>
/// 蓝色滤镜
/// </summary>
/// <param name="bitmap">一个图片实例</param>
/// <param name="threshold">阀值 -255~255</param>
/// <returns></returns>
public System.Drawing.Bitmap AdjustToBlue(System.Drawing.Bitmap bitmap, int threshold)
{
for (int y = ; y < bitmap.Height; y++)
{
for (int x = ; x < bitmap.Width; x++)
{
// 取得每一個 pixel
var pixel = bitmap.GetPixel(x, y);
//判斷是否超過255 如果超過就是255
var pB = pixel.B + threshold;
//如果小於0就為0
if (pB > ) pB = ;
if (pB < ) pB = ;
// 將改過的 RGB 寫回
// 只寫入藍色的值 , R G 都放零
System.Drawing.Color newColor = System.Drawing.Color.FromArgb(pixel.A, , , pB);
bitmap.SetPixel(x, y, newColor);
}
}
// 回傳結果
return bitmap;
}
/// <summary>
/// 调整 RGB 色调
/// </summary>
/// <param name="bitmap"></param>
/// <param name="thresholdRed">红色阀值</param>
/// <param name="thresholdBlue">蓝色阀值</param>
/// <param name="thresholdGreen">绿色阀值</param>
/// <returns></returns>
public System.Drawing.Bitmap AdjustToCustomColor(System.Drawing.Bitmap bitmap, int thresholdRed, int thresholdGreen, int thresholdBlue)
{
for (int y = ; y < bitmap.Height; y++)
{
for (int x = ; x < bitmap.Width; x++)
{
// 取得每一個 pixel
var pixel = bitmap.GetPixel(x, y);
//判斷是否超過255 如果超過就是255
var pG = pixel.G + thresholdGreen;
//如果小於0就為0
if (pG > ) pG = ;
if (pG < ) pG = ;
//判斷是否超過255 如果超過就是255
var pR = pixel.R + thresholdRed;
//如果小於0就為0
if (pR > ) pR = ;
if (pR < ) pR = ;
//判斷是否超過255 如果超過就是255
var pB = pixel.B + thresholdBlue;
//如果小於0就為0
if (pB > ) pB = ;
if (pB < ) pB = ;
// 將改過的 RGB 寫回
// 只寫入綠色的值 , R B 都放零
System.Drawing.Color newColor = System.Drawing.Color.FromArgb(pixel.A, pR, pG, pB);
bitmap.SetPixel(x, y, newColor);
}
}
return bitmap;
}
#endregion #region 图片去色(图片黑白化)
/// <summary>
/// 图片去色(图片黑白化)
/// </summary>
/// <param name="original">一个需要处理的图片</param>
/// <returns></returns>
public static Bitmap MakeGrayscale(Bitmap original)
{
//create a blank bitmap the same size as original
Bitmap newBitmap = new Bitmap(original.Width, original.Height); //get a graphics object from the new image
Graphics g = Graphics.FromImage(newBitmap);
g.SmoothingMode = SmoothingMode.HighQuality;
//create the grayscale ColorMatrix
ColorMatrix colorMatrix = new ColorMatrix(new float[][]
{
new float[] {.3f, .3f, .3f, , },
new float[] {.59f, .59f, .59f, , },
new float[] {.11f, .11f, .11f, , },
new float[] {, , , , },
new float[] {, , , , }
}); //create some image attributes
ImageAttributes attributes = new ImageAttributes(); //set the color matrix attribute
attributes.SetColorMatrix(colorMatrix); //draw the original image on the new image
//using the grayscale color matrix
g.DrawImage(original, new Rectangle(, , original.Width, original.Height),
, , original.Width, original.Height, GraphicsUnit.Pixel, attributes); //dispose the Graphics object
g.Dispose();
return newBitmap;
}
#endregion #region 增加或減少亮度
/// <summary>
/// 增加或減少亮度
/// </summary>
/// <param name="img">System.Drawing.Image Source </param>
/// <param name="valBrightness">0~255</param>
/// <returns></returns>
public System.Drawing.Bitmap AdjustBrightness(System.Drawing.Image img, int valBrightness)
{
// 讀入欲轉換的圖片並轉成為 Bitmap
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(img); for (int y = ; y < bitmap.Height; y++)
{
for (int x = ; x < bitmap.Width; x++)
{
// 取得每一個 pixel
var pixel = bitmap.GetPixel(x, y); // 判斷 如果處理過後 255 就設定為 255 如果小於則設定為 0
var pR = ((pixel.R + valBrightness > ) ? : pixel.R + valBrightness) < ? : ((pixel.R + valBrightness > ) ? : pixel.R + valBrightness);
var pG = ((pixel.G + valBrightness > ) ? : pixel.G + valBrightness) < ? : ((pixel.G + valBrightness > ) ? : pixel.G + valBrightness);
var pB = ((pixel.B + valBrightness > ) ? : pixel.B + valBrightness) < ? : ((pixel.B + valBrightness > ) ? : pixel.B + valBrightness); // 將改過的 RGB 寫回
System.Drawing.Color newColor = System.Drawing.Color.FromArgb(pixel.A, pR, pG, pB); bitmap.SetPixel(x, y, newColor); }
}
// 回傳結果
return bitmap;
}
#endregion #region 浮雕效果
/// <summary>
/// 浮雕效果
/// </summary>
/// <param name="src">一个图片实例</param>
/// <returns></returns>
public Bitmap AdjustToStone(Bitmap src)
{
// 依照 Format24bppRgb 每三个表示一 Pixel 0: 蓝 1: 绿 2: 红
BitmapData bitmapData = src.LockBits(new Rectangle(, , src.Width, src.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); unsafe
{
// 抓住第一个 Pixel 第一个数值
byte* p = (byte*)(void*)bitmapData.Scan0; // 跨步值 - 宽度 *3 可以算出畸零地 之后跳到下一行
int nOffset = bitmapData.Stride - src.Width * ; for (int y = ; y < src.Height; ++y)
{
for (int x = ; x < src.Width; ++x)
{
// 为了理解方便 所以特地在命名
int r, g, b;
// 先取得下一个 Pixel
var q = p + ;
r = Math.Abs(p[] - q[] + );
r = r < ? : r;
r = r > ? : r;
p[] = (byte)r; g = Math.Abs(p[] - q[] + );
g = g < ? : g;
g = g > ? : g;
p[] = (byte)g; b = Math.Abs(p[] - q[] + );
b = b < ? : b;
b = b > ? : b;
p[] = (byte)b; // 跳去下一个 Pixel
p += ; }
// 跨越畸零地
p += nOffset;
}
}
src.UnlockBits(bitmapData);
return src;
}
#endregion #region 水波纹效果
/// <summary>
/// 水波纹效果
/// </summary>
/// <param name="src"></param>
/// <param name="nWave">坡度</param>
/// www.it165.net
/// <returns></returns>
public Bitmap AdjustRippleEffect(Bitmap src, short nWave)
{ int nWidth = src.Width;
int nHeight = src.Height; // 透过公式进行水波纹的採样 PointF[,] fp = new PointF[nWidth, nHeight]; Point[,] pt = new Point[nWidth, nHeight]; Point mid = new Point();
mid.X = nWidth / ;
mid.Y = nHeight / ; double newX, newY;
double xo, yo; //先取样将水波纹座标跟RGB取出
for (int x = ; x < nWidth; ++x)
for (int y = ; y < nHeight; ++y)
{
xo = ((double)nWave * Math.Sin(2.0 * 3.1415 * (float)y / 128.0));
yo = ((double)nWave * Math.Cos(2.0 * 3.1415 * (float)x / 128.0)); newX = (x + xo);
newY = (y + yo); if (newX > && newX < nWidth)
{
fp[x, y].X = (float)newX;
pt[x, y].X = (int)newX;
}
else
{
fp[x, y].X = (float)0.0;
pt[x, y].X = ;
} if (newY > && newY < nHeight)
{
fp[x, y].Y = (float)newY;
pt[x, y].Y = (int)newY;
}
else
{
fp[x, y].Y = (float)0.0;
pt[x, y].Y = ;
}
} //进行合成
Bitmap bSrc = (Bitmap)src.Clone(); // 依照 Format24bppRgb 每三个表示一 Pixel 0: 蓝 1: 绿 2: 红
BitmapData bitmapData = src.LockBits(new Rectangle(, , src.Width, src.Height), ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);
BitmapData bmSrc = bSrc.LockBits(new Rectangle(, , bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb); int scanline = bitmapData.Stride; IntPtr Scan0 = bitmapData.Scan0;
IntPtr SrcScan0 = bmSrc.Scan0; unsafe
{
byte* p = (byte*)(void*)Scan0;
byte* pSrc = (byte*)(void*)SrcScan0; int nOffset = bitmapData.Stride - src.Width * ; int xOffset, yOffset; for (int y = ; y < nHeight; ++y)
{
for (int x = ; x < nWidth; ++x)
{
xOffset = pt[x, y].X;
yOffset = pt[x, y].Y; if (yOffset >= && yOffset < nHeight && xOffset >= && xOffset < nWidth)
{
p[] = pSrc[(yOffset * scanline) + (xOffset * )];
p[] = pSrc[(yOffset * scanline) + (xOffset * ) + ];
p[] = pSrc[(yOffset * scanline) + (xOffset * ) + ];
} p += ;
}
p += nOffset;
}
} src.UnlockBits(bitmapData);
bSrc.UnlockBits(bmSrc); return src;
}
#endregion #region 调整曝光度值
/// <summary>
/// 调整曝光度值
/// </summary>
/// <param name="src">原图</param>
/// <param name="r"></param>
/// <param name="g"></param>
/// <param name="b"></param>
/// <returns></returns>
public Bitmap AdjustGamma(Bitmap src, double r, double g, double b)
{
// 判断是不是在0.2~5 之间
r = Math.Min(Math.Max(0.2, r), );
g = Math.Min(Math.Max(0.2, g), );
b = Math.Min(Math.Max(0.2, b), ); // 依照 Format24bppRgb 每三个表示一 Pixel 0: 蓝 1: 绿 2: 红
BitmapData bitmapData = src.LockBits(new Rectangle(, , src.Width, src.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); unsafe
{
// 抓住第一个 Pixel 第一个数值
byte* p = (byte*)(void*)bitmapData.Scan0; // 跨步值 - 宽度 *3 可以算出畸零地 之后跳到下一行
int nOffset = bitmapData.Stride - src.Width * ; for (int y = ; y < src.Height; y++)
{
for (int x = ; x < src.Width; x++)
{
p[] = (byte)Math.Min(, (int)((255.0 * Math.Pow(p[] / 255.0, 1.0 / r)) + 0.5));
p[] = (byte)Math.Min(, (int)((255.0 * Math.Pow(p[] / 255.0, 1.0 / g)) + 0.5));
p[] = (byte)Math.Min(, (int)((255.0 * Math.Pow(p[] / 255.0, 1.0 / b)) + 0.5)); // 跳去下一个 Pixel
p += ; }
// 跨越畸零地
p += nOffset;
}
}
src.UnlockBits(bitmapData);
return src; }
#endregion #region 高对比,对过深的颜色调浅,过浅的颜色调深。
/// <summary>
/// 高对比,对过深的颜色调浅,过浅的颜色调深。
/// </summary>
/// <param name="src"></param>
/// <param name="effectThreshold"> 高对比程度 -100~100</param>
/// <returns></returns>
public Bitmap Contrast(Bitmap src, float effectThreshold)
{ // 依照 Format24bppRgb 每三个表示一 Pixel 0: 蓝 1: 绿 2: 红
BitmapData bitmapData = src.LockBits(new Rectangle(, , src.Width, src.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); // 判断是否在 -100~100
effectThreshold = effectThreshold < - ? - : effectThreshold;
effectThreshold = effectThreshold > ? : effectThreshold; effectThreshold = (float)((100.0 + effectThreshold) / 100.0);
effectThreshold *= effectThreshold; unsafe
{
// 抓住第一个 Pixel 第一个数值 www.it165.net
byte* p = (byte*)(void*)bitmapData.Scan0; // 跨步值 - 宽度 *3 可以算出畸零地 之后跳到下一行
int nOffset = bitmapData.Stride - src.Width * ; for (int y = ; y < src.Height; y++)
{
for (int x = ; x < src.Width; x++)
{
double buffer = ; // 公式 (Red/255)-0.5= 偏离中间值程度
// ((偏离中间值程度 * 影响范围)+0.4 ) * 255
buffer = ((((p[] / 255.0) - 0.5) * effectThreshold) + 0.5) * 255.0;
buffer = buffer > ? : buffer;
buffer = buffer < ? : buffer;
p[] = (byte)buffer; buffer = ((((p[] / 255.0) - 0.5) * effectThreshold) + 0.5) * 255.0;
buffer = buffer > ? : buffer;
buffer = buffer < ? : buffer;
p[] = (byte)buffer; buffer = ((((p[] / 255.0) - 0.5) * effectThreshold) + 0.5) * 255.0;
buffer = buffer > ? : buffer;
buffer = buffer < ? : buffer;
p[] = (byte)buffer; // 跳去下一个 Pixel
p += ; }
// 跨越畸零地
p += nOffset;
}
}
src.UnlockBits(bitmapData);
return src; }
#endregion #region 对图片进行雾化效果
/// <summary>
/// 对图片进行雾化效果
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
public Bitmap Atomization(Bitmap bmp)
{ int Height = bmp.Height;
int Width = bmp.Width;
Bitmap newBitmap = new Bitmap(Width, Height);
Bitmap oldBitmap = bmp;
Color pixel;
for (int x = ; x < Width - ; x++)
{
for (int y = ; y < Height - ; y++)
{
Random MyRandom = new Random( Guid.NewGuid().GetHashCode());
int k = MyRandom.Next();
//像素块大小
int dx = x + k % ;
int dy = y + k % ;
if (dx >= Width)
dx = Width - ;
if (dy >= Height)
dy = Height - ;
pixel = oldBitmap.GetPixel(dx, dy);
newBitmap.SetPixel(x, y, pixel);
}
}
return newBitmap;
}
#endregion } //END Class DrawValidationCode
#endregion #region 高斯模糊算法
/// <summary>
/// 高斯模糊算法
/// </summary>
public class Gaussian
{
public static double[,] Calculate1DSampleKernel(double deviation, int size)
{
double[,] ret = new double[size, ];
double sum = ;
int half = size / ;
for (int i = ; i < size; i++)
{
ret[i, ] = / (Math.Sqrt( * Math.PI) * deviation) * Math.Exp(-(i - half) * (i - half) / ( * deviation * deviation));
sum += ret[i, ];
}
return ret;
}
public static double[,] Calculate1DSampleKernel(double deviation)
{
int size = (int)Math.Ceiling(deviation * ) * + ;
return Calculate1DSampleKernel(deviation, size);
}
public static double[,] CalculateNormalized1DSampleKernel(double deviation)
{
return NormalizeMatrix(Calculate1DSampleKernel(deviation));
}
public static double[,] NormalizeMatrix(double[,] matrix)
{
double[,] ret = new double[matrix.GetLength(), matrix.GetLength()];
double sum = ;
for (int i = ; i < ret.GetLength(); i++)
{
for (int j = ; j < ret.GetLength(); j++)
sum += matrix[i, j];
}
if (sum != )
{
for (int i = ; i < ret.GetLength(); i++)
{
for (int j = ; j < ret.GetLength(); j++)
ret[i, j] = matrix[i, j] / sum;
}
}
return ret;
}
public static double[,] GaussianConvolution(double[,] matrix, double deviation)
{
double[,] kernel = CalculateNormalized1DSampleKernel(deviation);
double[,] res1 = new double[matrix.GetLength(), matrix.GetLength()];
double[,] res2 = new double[matrix.GetLength(), matrix.GetLength()];
//x-direction
for (int i = ; i < matrix.GetLength(); i++)
{
for (int j = ; j < matrix.GetLength(); j++)
res1[i, j] = processPoint(matrix, i, j, kernel, );
}
//y-direction
for (int i = ; i < matrix.GetLength(); i++)
{
for (int j = ; j < matrix.GetLength(); j++)
res2[i, j] = processPoint(res1, i, j, kernel, );
}
return res2;
}
private static double processPoint(double[,] matrix, int x, int y, double[,] kernel, int direction)
{
double res = ;
int half = kernel.GetLength() / ;
for (int i = ; i < kernel.GetLength(); i++)
{
int cox = direction == ? x + i - half : x;
int coy = direction == ? y + i - half : y;
if (cox >= && cox < matrix.GetLength() && coy >= && coy < matrix.GetLength())
{
res += matrix[cox, coy] * kernel[i, ];
}
}
return res;
}
/// <summary>
/// 对颜色值进行灰色处理
/// </summary>
/// <param name="cr"></param>
/// <returns></returns>
private Color grayscale(Color cr)
{
return Color.FromArgb(cr.A, (int)(cr.R * . + cr.G * . + cr.B * 0.11),
(int)(cr.R * . + cr.G * . + cr.B * 0.11),
(int)(cr.R * . + cr.G * . + cr.B * 0.11));
}
/// <summary>
/// 对图片进行高斯模糊
/// </summary>
/// <param name="d">模糊数值,数值越大模糊越很</param>
/// <param name="image">一个需要处理的图片</param>
/// <returns></returns>
public Bitmap FilterProcessImage(double d, Bitmap image)
{
Bitmap ret = new Bitmap(image.Width, image.Height);
Double[,] matrixR = new Double[image.Width, image.Height];
Double[,] matrixG = new Double[image.Width, image.Height];
Double[,] matrixB = new Double[image.Width, image.Height];
for (int i = ; i < image.Width; i++)
{
for (int j = ; j < image.Height; j++)
{
//matrix[i, j] = grayscale(image.GetPixel(i, j)).R;
matrixR[i, j] = image.GetPixel(i, j).R;
matrixG[i, j] = image.GetPixel(i, j).G;
matrixB[i, j] = image.GetPixel(i, j).B;
}
}
matrixR = Gaussian.GaussianConvolution(matrixR, d);
matrixG = Gaussian.GaussianConvolution(matrixG, d);
matrixB = Gaussian.GaussianConvolution(matrixB, d);
for (int i = ; i < image.Width; i++)
{
for (int j = ; j < image.Height; j++)
{
Int32 R = (int)Math.Min(, matrixR[i, j]);
Int32 G = (int)Math.Min(, matrixG[i, j]);
Int32 B = (int)Math.Min(, matrixB[i, j]);
ret.SetPixel(i, j, Color.FromArgb(R, G, B));
}
}
return ret;
} }
#endregion
}

最新文章

  1. 基于bootstrap 的datatable插件的使用2(php版)
  2. 三层架构下的EntityFramework codefirst
  3. 移动端布局,div按比例布局,宽度为百分比,高度和宽度一样,即让div为正方形
  4. android: SQLite使用 SQL 操作数据库
  5. iOS自动布局一
  6. 一个可无限伸缩且无ABA问题的无锁队列
  7. Tomcat启动报错java.lang.UnsatisfiedLinkError
  8. Aspose实现Office转PDF (ASP.NET)
  9. 简单总结下 cookie、session
  10. 通过iframe引入另外一个项目中的html片段到项目中,解决样式,高度,兼容等问题的策略
  11. CUDA编程模型之内存管理
  12. CLOUD清理临时表空间
  13. IOS获取资源路径
  14. python第四十七课——类属性和函数属性
  15. 电信运营商 IT 系统介绍
  16. 【PyQt5-Qt Designer】PyQt5+pyecharts 实现GUI界面的数据可视化展示
  17. Node.js之npm使用
  18. sleep php函数
  19. JDBC-自定义数据库工具类(DBService)
  20. linux2.4中netfilter_nat_alg机制分析--以FTP流程为例,分析NAT和ALG

热门文章

  1. ArcGIS学习推荐
  2. Python 去剑式
  3. springmvcIntercept(拦截器)
  4. HR函数学习02——分配组织单位
  5. iOS开发UI篇—在UITableview的应用中使用动态单元格来完成app应用程序管理界面的搭建
  6. iOS开发网络篇—发送json数据给服务器以及多值参数
  7. 利用JAVA想数据库中提交数据
  8. IOS时间传递机制简记
  9. qt搭建环境
  10. 实验三 java敏捷开发与XP