先看效果:

相对于 Web(B/S)生成模糊验证码的几种方式(转载) :

(1)去掉依赖session的代码,去掉继承自Page类。

(2)修改了贝塞尔曲线的线宽。

(3)优化了超过默认4位验证码报错问题。

 

asp.net mvc 调用代码:

 public ActionResult yanzhengma3()
        {
            DrawValidationCode objDrawValidationCode = new DrawValidationCode();
            objDrawValidationCode.ValidationCodeCount = 50;//验证码字符个数
            objDrawValidationCode.IsTwist = true;//是否扭曲
            objDrawValidationCode.IsRandString = true;//随机早点字符
            objDrawValidationCode.IsPixel = true;//随机噪点

            objDrawValidationCode.RandomStringCount = 8; //
            //objDrawValidationCode.RandomStringFontSize = 30;

            objDrawValidationCode.FontMinSize = 35;//验证码字体的大小的最小值
            objDrawValidationCode.FontMaxSize = 40;  //验证码字体的大小的最小值

            //objDrawValidationCode.GaussianDeviation = 3;    //默认0,不使用高斯模糊算法处理图像。
            //objDrawValidationCode.BrightnessValue = 5;        //明暗度,默认0,是使用明暗度算法处理图像

            objDrawValidationCode.LineCount = 0;  //默认3条。
            objDrawValidationCode.BezierCount = 2;//默认3条。
            


            using (MemoryStream ms = new MemoryStream())
            {
                objDrawValidationCode.CreateImage(ms);
                return File(ms.GetBuffer(), "image/jpeg");
            }
        }

验证码类全部代码(已亲自测试)

   1 using System;
   2 using System.Collections.Generic;
   3 using System.Drawing;
   4 using System.Drawing.Drawing2D;
   5 using System.Drawing.Imaging;
   6 using System.Drawing.Text;
   7 using System.IO;
   8 using System.Linq;
   9 using System.Text;
  10 
  11 namespace JBM.Web.util
  12 {
  13     #region 验证码生成类
  14     /// <summary>
  15     /// 验证码生成类
  16     /// </summary>
  17     public class DrawValidationCode
  18     {
  19         #region 定义和初始化配置字段
  20         //用户存取验证码字符串
  21         private string validationCode = String.Empty;
  22         /// <summary>
  23         /// 获取系统生成的随机验证码
  24         /// </summary>
  25         public String ValidationCode
  26         {
  27             get { return validationCode; }
  28         }
  29         private Int32 validationCodeCount = 4;
  30         /// <summary>
  31         /// 获取和设置验证码字符串的长度
  32         /// </summary>
  33         public Int32 ValidationCodeCount
  34         {
  35             get { return validationCodeCount; }
  36             set { validationCodeCount = value; }
  37         }
  38         Graphics dc = null;
  39         private int bgWidth = 130;
  40         /// <summary>
  41         /// 验证码的宽度,默认为80
  42         /// </summary>
  43         public Int32 Width
  44         {
  45             get { return bgWidth; }
  46             set { bgWidth = value; }
  47         }
  48 
  49         private int bgHeight = 40;
  50         /// <summary>
  51         /// 验证码的高度,默认为40
  52         /// </summary>
  53         public Int32 Height
  54         {
  55             get { return bgHeight; }
  56             set { bgHeight = value; }
  57         }
  58         /* private string[] fontFace = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" };
  59          /// <summary>
  60          /// 验证码字体列表,默认为{ "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" }
  61          /// </summary>
  62          public String[] FontFace
  63          {
  64              get { return fontFace; }
  65              set { fontFace = value; }
  66          }*/
  67 
  68         private int fontMinSize = 15;
  69         /// <summary>
  70         /// 验证码字体的最小值,默认为15,建议不小于15像素
  71         /// </summary>
  72         public Int32 FontMinSize
  73         {
  74             get { return fontMinSize; }
  75             set { fontMinSize = value; }
  76         }
  77         private Int32 fontMaxSize = 20;
  78         /// <summary>
  79         /// 验证码字体的最大值,默认为20
  80         /// </summary>
  81         public Int32 FontMaxSize
  82         {
  83             get { return fontMaxSize; }
  84             set { fontMaxSize = value; }
  85         }
  86         private Color[] fontColor = { };
  87         /// <summary>
  88         /// 验证码字体的颜色,默认为系统自动生成字体颜色
  89         /// </summary>
  90         public Color[] FontColor
  91         {
  92             get { return fontColor; }
  93             set { fontColor = value; }
  94         }
  95         private Color backColor = Color.FromArgb(243, 255, 255);
  96         /// <summary>
  97         /// 验证码的背景色,默认为Color.FromArgb(243, 251, 254)
  98         /// </summary>
  99         public Color BackgroundColor
 100         {
 101             get { return backColor; }
 102             set { backColor = value; }
 103         }
 104         private Int32 bezierCount = 3;
 105         /// <summary>
 106         /// 贝塞尔曲线的条数,默认为3条
 107         /// </summary>
 108         public Int32 BezierCount
 109         {
 110             get { return bezierCount; }
 111             set { bezierCount = value; }
 112         }
 113         private Int32 lineCount = 3;
 114         /// <summary>
 115         /// 直线条数,默认为3条
 116         /// </summary>
 117         public Int32 LineCount
 118         {
 119             get { return lineCount; }
 120             set { lineCount = value; }
 121         }
 122         Random random;
 123 
 124         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; 
 125         /// <summary>
 126         /// 随机字符串列表,请使用英文状态下的逗号分隔。
 127         /// </summary>
 128         public String CharCollection
 129         {
 130             get { return charCollection; }
 131             set { charCollection = value; }
 132         }
 133         private Int32 intCount = 4;
 134         /// <summary>
 135         /// 验证码字符串个数,默认为4个字符
 136         /// </summary>
 137         public Int32 IntCount
 138         {
 139             get { return intCount; }
 140             set { intCount = value; }
 141         }
 142         private Boolean isPixel = true;
 143         /// <summary>
 144         /// 是否添加噪点,默认添加,噪点颜色为系统随机生成。
 145         /// </summary>
 146         public Boolean IsPixel
 147         {
 148             get { return isPixel; }
 149             set { isPixel = value; }
 150         }
 151         private Boolean isRandString = true;
 152         /// <summary>
 153         /// 是否添加随机噪点字符串,默认添加
 154         /// </summary>
 155         public Boolean IsRandString
 156         {
 157             get { return isRandString; }
 158             set { isRandString = value; }
 159         }
 160         /// <summary>
 161         /// 随机背景字符串的个数
 162         /// </summary>
 163         public Int32 RandomStringCount
 164         {
 165             get;
 166             set;
 167         }
 168         private Int32 randomStringFontSize = 9;
 169         /// <summary>
 170         /// 随机背景字符串的大小
 171         /// </summary>
 172         public Int32 RandomStringFontSize
 173         {
 174             get { return randomStringFontSize; }
 175             set { randomStringFontSize = value; }
 176         }
 177         /// <summary>
 178         /// 是否对图片进行扭曲
 179         /// </summary>
 180         public Boolean IsTwist
 181         {
 182             get;
 183             set;
 184         }
 185         /// <summary>
 186         /// 边框样式
 187         /// </summary>
 188         public enum BorderStyle
 189         {
 190             /// <summary>
 191             /// 无边框
 192             /// </summary>
 193             None,
 194             /// <summary>
 195             /// 矩形边框
 196             /// </summary>
 197             Rectangle,
 198             /// <summary>
 199             /// 圆角边框
 200             /// </summary>
 201             RoundRectangle
 202         }
 203         private Int32 rotationAngle = 40;
 204         /// <summary>
 205         /// 验证码字符串随机转动的角度的最大值
 206         /// </summary>
 207         public Int32 RotationAngle
 208         {
 209             get { return rotationAngle; }
 210             set { rotationAngle = value; }
 211         }
 212         /// <summary>
 213         /// 设置或获取边框样式
 214         /// </summary>
 215         public BorderStyle Border
 216         {
 217             get;
 218             set;
 219         }
 220         private Point[] strPoint = null;
 221 
 222         private Double gaussianDeviation = 0;
 223         /// <summary>
 224         /// 对验证码图片进行高斯模糊的阀值,如果设置为0,则不对图片进行高斯模糊,该设置可能会对图片处理的性能有较大影响
 225         /// </summary>
 226         public Double GaussianDeviation
 227         {
 228             get { return gaussianDeviation; }
 229             set { gaussianDeviation = value; }
 230         }
 231         private Int32 brightnessValue = 0;
 232         /// <summary>
 233         /// 对图片进行暗度和亮度的调整,如果该值为0,则不调整。该设置会对图片处理性能有较大影响
 234         /// </summary>
 235         public Int32 BrightnessValue
 236         {
 237             get { return brightnessValue; }
 238             set { brightnessValue = value; }
 239         }
 240         #endregion
 241 
 242         #region wq 新增 边框补(默认1像素)
 243         int padding = 2;
 244         public int Padding
 245         {
 246             get { return padding; }
 247             set { padding = value; }
 248         }
 249         #endregion
 250 
 251         /// <summary>
 252         /// 构造函数,用于初始化常用变量
 253         /// </summary>
 254         public DrawValidationCode()
 255         {
 256             random = new Random(Guid.NewGuid().GetHashCode());
 257             strPoint = new Point[validationCodeCount + 1];
 258             if (gaussianDeviation < 0) gaussianDeviation = 0;
 259         }
 260 
 261         /// <summary>
 262         /// 生成验证码
 263         /// </summary>
 264         /// <param name="target">用于存储图片的一般字节序列</param>
 265         public MemoryStream CreateImage(MemoryStream target)
 266         {
 267             //新增 wq ,否则后面报错
 268             if (strPoint.Length != validationCodeCount)
 269             {
 270                 strPoint = new Point[validationCodeCount + 1];//wq 新增,原因是:构造函数默认初始化5个元素,假如new后,又改了validationCodeCount的数值,则该数字需要重新初始化
 271             }
 272 
 273             //新增 wq    ,否则图片的画布太小
 274             if (fontMaxSize >= (bgHeight / 5) * 4)
 275             {
 276                 //throw new ArgumentException("字体最大值参数FontMaxSize与验证码高度相近,这会导致描绘验证码字符串时出错,请重新设置参数!");
 277                 AdjustBitmapSize();
 278             }
 279 
 280             Bitmap bit = new Bitmap(bgWidth + 1, bgHeight + 1);
 281             //写字符串
 282             dc = Graphics.FromImage(bit);
 283             dc.SmoothingMode = SmoothingMode.HighQuality;
 284             dc.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; ;
 285             dc.InterpolationMode = InterpolationMode.HighQualityBilinear;
 286             dc.CompositingQuality = CompositingQuality.HighQuality;
 287 
 288             dc.Clear(Color.White);
 289             dc.DrawImageUnscaled(DrawBackground(), 0, 0);
 290 
 291             //绘制随机码
 292             Bitmap validatecodeImg = DrawRandomString();
 293             //对随机码图像上的文字进行波形扭曲(扭曲文字方式1)
 294             validatecodeImg = TwistImage(validatecodeImg, true, 8, 4);
 295             dc.DrawImageUnscaled(validatecodeImg, 0, 0);
 296 
 297             //水波纹效果  文字进行波形扭曲 (扭曲文字方式2)
 298             //bit = AdjustRippleEffect(bit, 5);
 299 
 300 
 301             //对图片进行高斯模糊
 302             if (gaussianDeviation > 0)
 303             {
 304                 Gaussian gau = new Gaussian();
 305                 bit = gau.FilterProcessImage(gaussianDeviation, bit);
 306             }
 307             //进行暗度和亮度处理
 308             if (brightnessValue != 0)
 309             {
 310                 //对图片进行调暗处理
 311                 bit = AdjustBrightness(bit, brightnessValue);
 312             }
 313             bit.Save(target, ImageFormat.Gif);
 314             //brush.Dispose();
 315             bit.Dispose();
 316             dc.Dispose();
 317             return target;
 318         }
 319 
 320         #region 画验证码背景,例如,增加早点,添加曲线和直线等
 321         /// <summary>
 322         /// 画验证码背景,例如,增加早点,添加曲线和直线等
 323         /// </summary>
 324         /// <returns></returns>
 325         private Bitmap DrawBackground()
 326         {
 327             Bitmap bit = new Bitmap(bgWidth + 1, bgHeight + 1);
 328             Graphics g = Graphics.FromImage(bit);
 329             g.SmoothingMode = SmoothingMode.HighQuality;
 330 
 331             g.Clear(Color.White);
 332             Rectangle rectangle = new Rectangle(0, 0, bgWidth, bgHeight);
 333             Brush brush = new SolidBrush(backColor);
 334             g.FillRectangle(brush, rectangle);
 335 
 336             //画噪点
 337             if (isPixel)
 338             {
 339                 g.DrawImageUnscaled(DrawRandomPixel(30), 0, 0);
 340             }
 341             g.DrawImageUnscaled(DrawRandBgString(), 0, 0);
 342 
 343 
 344             //画曲线
 345             g.DrawImageUnscaled(DrawRandomBezier(bezierCount), 0, 0);
 346             //画直线
 347             g.DrawImageUnscaled(DrawRandomLine(lineCount), 0, 0);
 348 
 349             //dc.DrawImageUnscaled(DrawStringline(), 0, 0);
 350             if (Border == BorderStyle.Rectangle)
 351             {
 352                 //绘制边框
 353                 g.DrawRectangle(new Pen(Color.FromArgb(90, 87, 46)), 0, 0, bgWidth, bgHeight);
 354             }
 355             else if (Border == BorderStyle.RoundRectangle)
 356             {
 357                 //画圆角
 358                 DrawRoundRectangle(g, rectangle, Color.FromArgb(90, 87, 46), 1, 3);
 359             }
 360 
 361             return bit;
 362 
 363         }
 364         #endregion
 365 
 366         #region 画正弦曲线
 367         private Bitmap DrawTwist(Bitmap bmp, Int32 tWidth, Int32 tHeight, float angle, Color color)
 368         {
 369             //为了方便查看效果,在这里我定义了一个常量。
 370             //它在定义数组的长度和for循环中都要用到。
 371             int size = bgWidth;
 372 
 373             double[] x = new double[size];
 374             Bitmap b = new Bitmap(bmp.Width, bmp.Height);
 375             b.MakeTransparent();
 376             Graphics graphics = Graphics.FromImage(b);
 377             Pen pen = new Pen(color);
 378 
 379             //画正弦曲线的横轴间距参数。建议所用的值应该是 正数且是2的倍数。
 380             //在这里采用2。
 381             int val = 2;
 382 
 383             float temp = 0.0f;
 384 
 385             //把画布下移100。为什么要这样做,只要你把这一句给注释掉,运行一下代码,
 386             //你就会明白是为什么?
 387             graphics.TranslateTransform(0, 100);
 388             graphics.SmoothingMode = SmoothingMode.HighQuality;
 389             graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
 390             for (int i = 0; i < size; i++)
 391             {
 392                 //改变tWidth,实现正弦曲线宽度的变化。
 393                 //改tHeight,实现正弦曲线高度的变化。
 394                 x[i] = Math.Sin(2 * Math.PI * i / tWidth) * tHeight;
 395 
 396                 graphics.DrawLine(pen, i * val, temp, i * val + val / 2, (float)x[i]);
 397                 temp = (float)x[i];
 398             }
 399             graphics.RotateTransform(60, MatrixOrder.Prepend);
 400 
 401             //旋转图片
 402             // b = KiRotate(b, angle, Color.Transparent);
 403             return b;
 404         }
 405         #endregion
 406 
 407         #region 正弦曲线Wave扭曲图片
 408         /// <summary>
 409         /// 正弦曲线Wave扭曲图片
 410         /// </summary>
 411         /// <param name="srcBmp">图片路径</param>
 412         /// <param name="bXDir">如果扭曲则选择为True</param>
 413         /// <param name="dMultValue">波形的幅度倍数,越大扭曲的程度越高,一般为3</param>
 414         /// <param name="dPhase">波形的起始相位,取值区间[0-2*PI)</param>
 415         /// <returns></returns>
 416         public Bitmap TwistImage(Bitmap srcBmp, bool bXDir, double dMultValue, double dPhase)
 417         {
 418             System.Drawing.Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height);
 419             double PI2 = 6.283185307179586476925286766559;
 420             // 将位图背景填充为白色
 421             System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(destBmp);
 422             graph.FillRectangle(new SolidBrush(System.Drawing.Color.White), 0, 0, destBmp.Width, destBmp.Height);
 423             graph.Dispose();
 424 
 425             double dBaseAxisLen = bXDir ? (double)destBmp.Height : (double)destBmp.Width;
 426 
 427             for (int i = 0; i < destBmp.Width; i++)
 428             {
 429                 for (int j = 0; j < destBmp.Height; j++)
 430                 {
 431                     double dx = 0;
 432                     dx = bXDir ? (PI2 * (double)j) / dBaseAxisLen : (PI2 * (double)i) / dBaseAxisLen;
 433                     dx += dPhase;
 434                     double dy = Math.Sin(dx);
 435 
 436                     // 取得当前点的颜色
 437                     int nOldX = 0, nOldY = 0;
 438                     nOldX = bXDir ? i + (int)(dy * dMultValue) : i;
 439                     nOldY = bXDir ? j : j + (int)(dy * dMultValue);
 440 
 441                     System.Drawing.Color color = srcBmp.GetPixel(i, j);
 442                     if (nOldX >= 0 && nOldX < destBmp.Width
 443                      && nOldY >= 0 && nOldY < destBmp.Height)
 444                     {
 445                         destBmp.SetPixel(nOldX, nOldY, color);
 446                     }
 447                 }
 448             }
 449             return destBmp;
 450         }
 451         #endregion
 452 
 453         #region 图片任意角度旋转
 454         /// <summary>
 455         /// 图片任意角度旋转
 456         /// </summary>
 457         /// <param name="bmp">原始图Bitmap</param>
 458         /// <param name="angle">旋转角度</param>
 459         /// <param name="bkColor">背景色</param>
 460         /// <returns>输出Bitmap</returns>
 461         public static Bitmap KiRotate(Bitmap bmp, float angle, Color bkColor)
 462         {
 463             int w = bmp.Width;
 464             int h = bmp.Height;
 465 
 466             PixelFormat pf;
 467 
 468             if (bkColor == Color.Transparent)
 469             {
 470                 pf = PixelFormat.Format32bppArgb;
 471             }
 472             else
 473             {
 474                 pf = bmp.PixelFormat;
 475             }
 476 
 477             Bitmap tmp = new Bitmap(w, h, pf);
 478             Graphics g = Graphics.FromImage(tmp);
 479             g.Clear(bkColor);
 480             g.DrawImageUnscaled(bmp, 1, 1);
 481             g.Dispose();
 482 
 483             GraphicsPath path = new GraphicsPath();
 484             path.AddRectangle(new RectangleF(0f, 0f, w, h));
 485             Matrix mtrx = new Matrix();
 486             mtrx.Rotate(angle);
 487             RectangleF rct = path.GetBounds(mtrx);
 488 
 489             Bitmap dst = new Bitmap((int)rct.Width, (int)rct.Height, pf);
 490             g = Graphics.FromImage(dst);
 491             g.Clear(bkColor);
 492             g.TranslateTransform(-rct.X, -rct.Y);
 493             g.RotateTransform(angle);
 494             g.InterpolationMode = InterpolationMode.HighQualityBilinear;
 495             g.DrawImageUnscaled(tmp, 0, 0);
 496             g.Dispose();
 497             tmp.Dispose();
 498 
 499             return dst;
 500         }
 501         #endregion
 502 
 503         #region 随机生成贝塞尔曲线
 504         /// <summary>
 505         /// 随机生成贝塞尔曲线
 506         /// </summary>
 507         /// <param name="bmp">一个图片的实例</param>
 508         /// <param name="lineNum">线条数量</param>
 509         /// <returns></returns>
 510         public Bitmap DrawRandomBezier(Int32 lineNum)
 511         {
 512             Bitmap b = new Bitmap(bgWidth, bgHeight);
 513             b.MakeTransparent();
 514             Graphics g = Graphics.FromImage(b);
 515             g.Clear(Color.Transparent);
 516             g.SmoothingMode = SmoothingMode.HighQuality;
 517             g.PixelOffsetMode = PixelOffsetMode.HighQuality;
 518 
 519             GraphicsPath gPath1 = new GraphicsPath();
 520             Int32 lineRandNum = random.Next(lineNum);
 521 
 522             for (int i = 0; i < (lineNum - lineRandNum); i++)
 523             {
 524                 Pen p = new Pen(GetRandomDeepColor(),3f);  //wq,增加贝塞尔曲线的线宽参数
 525                 Point[] point = {
 526                                     new Point(random.Next(1, (b.Width / 10)), random.Next(1, (b.Height))),
 527                                     new Point(random.Next((b.Width / 10) * 2, (b.Width / 10) * 4), random.Next(1, (b.Height))),
 528                                     new Point(random.Next((b.Width / 10) * 4, (b.Width / 10) * 6), random.Next(1, (b.Height))),
 529                                     new Point(random.Next((b.Width / 10) * 8, b.Width), random.Next(1, (b.Height)))
 530                                 };
 531 
 532                 gPath1.AddBeziers(point);
 533                 g.DrawPath(p, gPath1);
 534                 p.Dispose();
 535             }
 536             
 537             for (int i = 0; i < lineRandNum; i++)
 538             {
 539                 Pen p = new Pen(GetRandomDeepColor());
 540                 Point[] point = {
 541                             new Point(random.Next(1, b.Width), random.Next(1, b.Height)),
 542                             new Point(random.Next((b.Width / 10) * 2, b.Width), random.Next(1, b.Height)),
 543                             new Point(random.Next((b.Width / 10) * 4, b.Width), random.Next(1, b.Height)),
 544                             new Point(random.Next(1, b.Width), random.Next(1, b.Height))
 545                                 };
 546                 gPath1.AddBeziers(point);
 547                 g.DrawPath(p, gPath1);
 548                 p.Dispose();
 549             }
 550             return b;
 551         }
 552         #endregion
 553 
 554         #region 画直线
 555         /// <summary>
 556         /// 画直线
 557         /// </summary>
 558         /// <param name="bmp">一个bmp实例</param>
 559         /// <param name="lineNum">线条个数</param>
 560         /// <returns></returns>
 561         public Bitmap DrawRandomLine(Int32 lineNum)
 562         {
 563             if (lineNum < 0) throw new ArgumentNullException("参数bmp为空!");
 564             Bitmap b = new Bitmap(bgWidth, bgHeight);
 565             b.MakeTransparent();
 566             Graphics g = Graphics.FromImage(b);
 567             g.Clear(Color.Transparent);
 568             g.PixelOffsetMode = PixelOffsetMode.HighQuality;
 569             g.SmoothingMode = SmoothingMode.HighQuality;
 570             for (int i = 0; i < lineNum; i++)
 571             {
 572                 Pen p = new Pen(GetRandomDeepColor());
 573                 Point pt1 = new Point(random.Next(1, (b.Width / 5) * 2), random.Next(b.Height));
 574                 Point pt2 = new Point(random.Next((b.Width / 5) * 3, b.Width), random.Next(b.Height));
 575                 g.DrawLine(p, pt1, pt2);
 576                 p.Dispose();
 577             }
 578 
 579             return b;
 580         }
 581         #endregion
 582 
 583         #region 画随机噪点
 584         /// <summary>
 585         /// 画随机噪点
 586         /// </summary>
 587         /// <param name="pixNum">噪点的百分比</param>
 588         /// <returns></returns>
 589         public Bitmap DrawRandomPixel(Int32 pixNum)
 590         {
 591             Bitmap b = new Bitmap(bgWidth, bgHeight);
 592             b.MakeTransparent();
 593             Graphics graph = Graphics.FromImage(b);
 594             graph.SmoothingMode = SmoothingMode.HighQuality;
 595             graph.InterpolationMode = InterpolationMode.HighQualityBilinear;
 596 
 597             //画噪点
 598             for (int i = 0; i < (bgHeight * bgWidth) / pixNum; i++)
 599             {
 600                 int x = random.Next(b.Width);
 601                 int y = random.Next(b.Height);
 602                 b.SetPixel(x, y, GetRandomDeepColor());
 603                 //下移坐标重新画点
 604                 if ((x + 1) < b.Width && (y + 1) < b.Height)
 605                 {
 606                     //画图片的前景噪音点
 607                     graph.DrawRectangle(new Pen(Color.Silver), random.Next(b.Width), random.Next(b.Height), 1, 1);
 608                 }
 609 
 610             }
 611 
 612             return b;
 613         }
 614         #endregion
 615 
 616         #region 画随机字符串中间连线
 617         /// <summary>
 618         /// 画随机字符串中间连线
 619         /// </summary>
 620         /// <returns></returns>
 621         private Bitmap DrawStringline()
 622         {
 623             Bitmap b = new Bitmap(bgWidth, bgHeight);
 624             b.MakeTransparent();
 625             Graphics g = Graphics.FromImage(b);
 626             g.SmoothingMode = SmoothingMode.AntiAlias;
 627 
 628             Point[] p = new Point[validationCodeCount];
 629             for (int i = 0; i < validationCodeCount; i++)
 630             {
 631                 p[i] = strPoint[i];
 632                 //throw new Exception(strPoint.Length.ToString());
 633             }
 634             // g.DrawBezier(new Pen(GetRandomDeepColor()), strPoint);
 635             //g.DrawClosedCurve(new Pen(GetRandomDeepColor()), strPoint);
 636             g.DrawCurve(new Pen(GetRandomDeepColor(), 1), strPoint);
 637 
 638             return b;
 639         }
 640         #endregion
 641 
 642         #region 写入验证码的字符串
 643         /// <summary>
 644         /// 写入验证码的字符串
 645         /// </summary>
 646         private Bitmap DrawRandomString()
 647         {
 648             if (fontMaxSize >= (bgHeight / 5) * 4)
 649             {
 650                 //throw new ArgumentException("字体最大值参数FontMaxSize与验证码高度相近,这会导致描绘验证码字符串时出错,请重新设置参数!");
 651                 AdjustBitmapSize();
 652             }
 653 
 654             
 655             Bitmap b = new Bitmap(bgWidth, bgHeight);
 656             b.MakeTransparent();
 657             Graphics g = Graphics.FromImage(b);
 658 
 659             g.Clear(Color.Transparent);
 660             g.PixelOffsetMode = PixelOffsetMode.Half;
 661             g.SmoothingMode = SmoothingMode.HighQuality;
 662             g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
 663             g.InterpolationMode = InterpolationMode.HighQualityBilinear;
 664 
 665             char[] chars = GetRandomString(validationCodeCount).ToCharArray();//拆散字符串成单字符数组
 666             validationCode = chars.ToString(); //这个类的外部,也可以通过这个参数,获取到本次的验证码字符串值。
 667 
 668             //设置字体显示格式
 669             StringFormat format = new StringFormat(StringFormatFlags.NoClip);
 670             format.Alignment = StringAlignment.Center;
 671             format.LineAlignment = StringAlignment.Center;
 672             FontFamily f = new FontFamily(GenericFontFamilies.Monospace);
 673 
 674 
 675             Int32 charNum = chars.Length;
 676 
 677             Point sPoint = new Point();
 678             Int32 fontSize = 9;
 679             for (int i = 0; i < validationCodeCount; i++)
 680             {
 681                 int findex = random.Next(validationCodeCount+1);// random.Next(5);
 682                 //定义字体
 683                 Font textFont = new Font(f, random.Next(fontMinSize, fontMaxSize), FontStyle.Bold);
 684                 //定义画刷,用于写字符串
 685                 //Brush brush = new SolidBrush(GetRandomDeepColor());
 686                 Int32 textFontSize = Convert.ToInt32(textFont.Size);
 687                 fontSize = textFontSize;
 688                 Point point = new Point(random.Next((bgWidth / charNum) * i + 5, (bgWidth / charNum) * (i + 1)), random.Next(bgHeight / 5 + textFontSize / 2, bgHeight - textFontSize / 2));
 689 
 690 
 691 
 692                 //如果当前字符X坐标小于字体的二分之一大小
 693                 if (point.X < textFontSize / 2)
 694                 {
 695                     point.X = point.X + textFontSize / 2;
 696                 }
 697                 //防止文字叠加
 698                 if (i > 0 && (point.X - sPoint.X < (textFontSize / 2 + textFontSize / 2)))
 699                 {
 700                     point.X = point.X + textFontSize;
 701                 }
 702                 //如果当前字符X坐标大于图片宽度,就减去字体的宽度
 703                 if (point.X > (bgWidth - textFontSize / 2))
 704                 {
 705                     point.X = bgWidth - textFontSize / 2;
 706                 }
 707 
 708                 sPoint = point;
 709 
 710                 float angle = random.Next(-rotationAngle, rotationAngle);//转动的度数
 711                 g.TranslateTransform(point.X, point.Y);//移动光标到指定位置
 712                 g.RotateTransform(angle);
 713 
 714                 //设置渐变画刷 
 715                 Rectangle myretang = new Rectangle(0, 1, Convert.ToInt32(textFont.Size), Convert.ToInt32(textFont.Size));
 716                 Color c = GetRandomDeepColor();
 717                 LinearGradientBrush mybrush2 = new LinearGradientBrush(myretang, c, GetLightColor(c, 120), random.Next(180));
 718 
 719                 g.DrawString(chars[i].ToString(), textFont, mybrush2, 1, 1, format);
 720 
 721                 g.RotateTransform(-angle);//转回去
 722                 g.TranslateTransform(-point.X, -point.Y);//移动光标到指定位置,每个字符紧凑显示,避免被软件识别
 723 
 724                 strPoint[i] = point;
 725 
 726                 textFont.Dispose();
 727                 mybrush2.Dispose();
 728             }
 729             return b;
 730         } 
 731         #endregion
 732 
 733         #region   wq 新增的矫正验证码的宽高
 734         private void AdjustBitmapSize()
 735         {
 736             int fSize = fontMaxSize;
 737             int fWidth = fSize + Padding;
 738 
 739             int imageWidth = (int)(validationCodeCount * fWidth) + 4 + Padding * 2;
 740             int imageHeight = fSize * 2 + Padding; 
 741             bgWidth = imageWidth;
 742             bgHeight = imageHeight;
 743         }
 744         #endregion
 745 
 746         #region 画干扰背景文字
 747         /// <summary>
 748         /// 画背景干扰文字
 749         /// </summary>
 750         /// <returns></returns>
 751         private Bitmap DrawRandBgString()
 752         {
 753             Bitmap b = new Bitmap(bgWidth, bgHeight);
 754             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" };
 755             b.MakeTransparent();
 756             Graphics g = Graphics.FromImage(b);
 757 
 758             g.Clear(Color.Transparent);
 759             g.PixelOffsetMode = PixelOffsetMode.HighQuality;
 760             g.SmoothingMode = SmoothingMode.HighQuality;
 761             g.TextRenderingHint = TextRenderingHint.AntiAlias;
 762             g.InterpolationMode = InterpolationMode.HighQualityBilinear;
 763 
 764             //设置字体显示格式
 765             StringFormat format = new StringFormat(StringFormatFlags.NoClip);
 766             format.Alignment = StringAlignment.Center;
 767             format.LineAlignment = StringAlignment.Center;
 768 
 769             FontFamily f = new FontFamily(GenericFontFamilies.Serif);
 770             Font textFont = new Font(f, randomStringFontSize, FontStyle.Underline);
 771 
 772             int randAngle = 60; //随机转动角度
 773 
 774             for (int i = 0; i < RandomStringCount; i++)
 775             {
 776 
 777                 Brush brush = new System.Drawing.SolidBrush(GetRandomLightColor());
 778                 Point pot = new Point(random.Next(5, bgWidth - 5), random.Next(5, bgHeight - 5));
 779                 //随机转动的度数
 780                 float angle = random.Next(-randAngle, randAngle);
 781 
 782                 //转动画布
 783                 g.RotateTransform(angle);
 784                 g.DrawString(randStr[random.Next(randStr.Length)], textFont, brush, pot, format);
 785                 //转回去,为下一个字符做准备
 786                 g.RotateTransform(-angle);
 787                 //释放资源
 788                 brush.Dispose();
 789             }
 790             textFont.Dispose();
 791             format.Dispose();
 792             f.Dispose();
 793 
 794             return b;
 795         }
 796         #endregion
 797 
 798         #region 生成随机字符串
 799         /// <summary>
 800         /// 生成随机字符串   
 801         /// </summary>
 802         /// <returns></returns>
 803         private string GetRandomString(Int32 textLength)
 804         {
 805             string[] randomArray = charCollection.Split(','); //将字符串生成数组    
 806             int arrayLength = randomArray.Length;
 807             string randomString = "";
 808             for (int i = 0; i < textLength; i++)
 809             {
 810                 randomString += randomArray[random.Next(0, arrayLength)];
 811             }
 812             //Session["CheckCode"] = randomString;
 813             return randomString; //长度是textLength +1
 814         }
 815         #endregion
 816 
 817         #region 内部方法:绘制验证码背景
 818         private void DrawBackground(HatchStyle hatchStyle)
 819         {
 820             //设置填充背景时用的笔刷
 821             HatchBrush hBrush = new HatchBrush(hatchStyle, backColor);
 822 
 823             //填充背景图片
 824             dc.FillRectangle(hBrush, 0, 0, this.bgWidth, this.bgHeight);
 825         }
 826         #endregion
 827 
 828         #region 根据指定长度,返回随机验证码
 829         /// <summary>
 830         /// 根据指定长度,返回随机验证码
 831         /// </summary>
 832         /// <param >制定长度</param>
 833         /// <returns>随即验证码</returns>
 834         public string Next(int length)
 835         {
 836             this.validationCode = GetRandomCode(length);
 837             return this.validationCode;
 838         }
 839         #endregion
 840 
 841         #region 内部方法:返回指定长度的随机验证码字符串
 842         /// <summary>
 843         /// 根据指定大小返回随机验证码
 844         /// </summary>
 845         /// <param >字符串长度</param>
 846         /// <returns>随机字符串</returns>
 847         private string GetRandomCode(int length)
 848         {
 849             StringBuilder sb = new StringBuilder(6);
 850 
 851             for (int i = 0; i < length; i++)
 852             {
 853                 sb.Append(Char.ConvertFromUtf32(RandomAZ09()));
 854             }
 855 
 856             return sb.ToString();
 857         }
 858         #endregion
 859 
 860         #region 内部方法:产生随机数和随机点
 861 
 862         /// <summary>
 863         /// 产生0-9A-Z的随机字符代码
 864         /// </summary>
 865         /// <returns>字符代码</returns>
 866         private int RandomAZ09()
 867         {
 868             int result = 48;
 869             Random ram = new Random();
 870             int i = ram.Next(2);
 871 
 872             switch (i)
 873             {
 874                 case 0:
 875                     result = ram.Next(48, 58);
 876                     break;
 877                 case 1:
 878                     result = ram.Next(65, 91);
 879                     break;
 880             }
 881 
 882             return result;
 883         }
 884 
 885         /// <summary>
 886         /// 返回一个随机点,该随机点范围在验证码背景大小范围内
 887         /// </summary>
 888         /// <returns>Point对象</returns>
 889         private Point RandomPoint()
 890         {
 891             Random ram = new Random();
 892             Point point = new Point(ram.Next(this.bgWidth), ram.Next(this.bgHeight));
 893             return point;
 894         }
 895         #endregion
 896 
 897         #region 随机生成颜色值
 898         /// <summary>
 899         /// 生成随机深颜色
 900         /// </summary>
 901         /// <returns></returns>
 902         public Color GetRandomDeepColor()
 903         {
 904             int nRed, nGreen, nBlue;    // nBlue,nRed  nGreen 相差大一点 nGreen 小一些
 905             //int high = 255;      
 906             int redLow = 160;
 907             int greenLow = 100;
 908             int blueLow = 160;
 909             nRed = random.Next(redLow);
 910             nGreen = random.Next(greenLow);
 911             nBlue = random.Next(blueLow);
 912             Color color = Color.FromArgb(nRed, nGreen, nBlue);
 913             return color;
 914         }
 915 
 916         /// <summary>
 917         /// 生成随机浅颜色
 918         /// </summary>
 919         /// <returns>randomColor</returns>
 920         public Color GetRandomLightColor()
 921         {
 922             int nRed, nGreen, nBlue;    //越大颜色越浅
 923             int low = 180;           //色彩的下限
 924             int high = 255;          //色彩的上限     
 925             nRed = random.Next(high) % (high - low) + low;
 926             nGreen = random.Next(high) % (high - low) + low;
 927             nBlue = random.Next(high) % (high - low) + low;
 928             Color color = Color.FromArgb(nRed, nGreen, nBlue);
 929             return color;
 930         }
 931         /// <summary>
 932         /// 生成随机颜色值
 933         /// </summary>
 934         /// <returns></returns>
 935         public Color GetRandomColor()
 936         {
 937             int nRed, nGreen, nBlue;    //越大颜色越浅
 938             int low = 10;           //色彩的下限
 939             int high = 255;          //色彩的上限   
 940             nRed = random.Next(high) % (high - low) + low;
 941             nGreen = random.Next(high) % (high - low) + low;
 942             nBlue = random.Next(high) % (high - low) + low;
 943             Color color = Color.FromArgb(nRed, nGreen, nBlue);
 944             return color;
 945         }
 946         /// <summary>
 947         /// 获取与当前颜色值相加后的颜色
 948         /// </summary>
 949         /// <param name="c"></param>
 950         /// <returns></returns>
 951         public Color GetLightColor(Color c, Int32 value)
 952         {
 953             int nRed = c.R, nGreen = c.G, nBlue = c.B;    //越大颜色越浅
 954             if (nRed + value < 255 && nRed + value > 0)
 955             {
 956                 nRed = c.R + 40;
 957             }
 958             if (nGreen + value < 255 && nGreen + value > 0)
 959             {
 960                 nGreen = c.G + 40;
 961             }
 962             if (nBlue + value < 255 && nBlue + value > 0)
 963             {
 964                 nBlue = c.B + 40;
 965             }
 966             Color color = Color.FromArgb(nRed, nGreen, nBlue);
 967             return color;
 968         }
 969         #endregion
 970 
 971         #region 合并图片
 972         /// <summary>      
 973         /// 合并图片       
 974         /// </summary>       
 975         /// <param name="maps"></param>       
 976         /// <returns></returns>       
 977         private Bitmap MergerImg(params Bitmap[] maps)
 978         {
 979             int i = maps.Length;
 980             if (i == 0)
 981                 throw new Exception("图片数不能够为0");
 982             //创建要显示的图片对象,根据参数的个数设置宽度           
 983             Bitmap backgroudImg = new Bitmap(i * 12, 16);
 984             Graphics g = Graphics.FromImage(backgroudImg);
 985             //清除画布,背景设置为白色           
 986             g.Clear(System.Drawing.Color.White);
 987             for (int j = 0; j < i; j++)
 988             {
 989                 //g.DrawImage(maps[j], j * 11, 0, maps[j].Width, maps[j].Height);
 990                 g.DrawImageUnscaled(maps[j], 0, 0);
 991             }
 992             g.Dispose();
 993             return backgroudImg;
 994         }
 995         #endregion
 996 
 997         #region 生成不重复的随机数,该函数会消耗大量系统资源
 998         /// <summary>
 999         /// 生成不重复的随机数,该函数会消耗大量系统资源
1000         /// </summary>
1001         /// <returns></returns>
1002         private static int GetRandomSeed()
1003         {
1004             byte[] bytes = new byte[4];
1005             System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
1006             rng.GetBytes(bytes);
1007             return BitConverter.ToInt32(bytes, 0);
1008         }
1009         #endregion
1010 
1011         #region 缩放图片
1012         /// <summary>
1013         /// 缩放图片
1014         /// </summary>
1015         /// <param name="bmp">原始Bitmap</param>
1016         /// <param name="newW">新的宽度</param>
1017         /// <param name="newH">新的高度</param>
1018         /// <param name="Mode">缩放质量</param>
1019         /// <returns>处理以后的图片</returns>
1020         public static Bitmap KiResizeImage(Bitmap bmp, int newW, int newH, InterpolationMode Mode)
1021         {
1022             try
1023             {
1024                 Bitmap b = new Bitmap(newW, newH);
1025                 Graphics g = Graphics.FromImage(b);
1026                 // 插值算法的质量
1027                 g.InterpolationMode = Mode;
1028                 g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
1029                 g.Dispose();
1030                 return b;
1031             }
1032             catch
1033             {
1034                 return null;
1035             }
1036         }
1037         #endregion
1038 
1039         #region 绘制圆角矩形
1040         /// <summary>
1041         /// C# GDI+ 绘制圆角矩形
1042         /// </summary>
1043         /// <param name="g">Graphics 对象</param>
1044         /// <param name="rectangle">Rectangle 对象,圆角矩形区域</param>
1045         /// <param name="borderColor">边框颜色</param>
1046         /// <param name="borderWidth">边框宽度</param>
1047         /// <param name="r">圆角半径</param>
1048         private static void DrawRoundRectangle(Graphics g, Rectangle rectangle, Color borderColor, float borderWidth, int r)
1049         {
1050             // 如要使边缘平滑,请取消下行的注释
1051             g.SmoothingMode = SmoothingMode.HighQuality;
1052 
1053             // 由于边框也需要一定宽度,需要对矩形进行修正
1054             //rectangle = new Rectangle(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
1055             Pen p = new Pen(borderColor, borderWidth);
1056             // 调用 getRoundRectangle 得到圆角矩形的路径,然后再进行绘制
1057             g.DrawPath(p, getRoundRectangle(rectangle, r));
1058         }
1059         #endregion
1060 
1061         #region 根据普通矩形得到圆角矩形的路径
1062         /// <summary>
1063         /// 根据普通矩形得到圆角矩形的路径
1064         /// </summary>
1065         /// <param name="rectangle">原始矩形</param>
1066         /// <param name="r">半径</param>
1067         /// <returns>图形路径</returns>
1068         private static GraphicsPath getRoundRectangle(Rectangle rectangle, int r)
1069         {
1070             int l = 2 * r;
1071             // 把圆角矩形分成八段直线、弧的组合,依次加到路径中
1072             GraphicsPath gp = new GraphicsPath();
1073             gp.AddLine(new Point(rectangle.X + r, rectangle.Y), new Point(rectangle.Right - r, rectangle.Y));
1074             gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Y, l, l), 270F, 90F);
1075 
1076             gp.AddLine(new Point(rectangle.Right, rectangle.Y + r), new Point(rectangle.Right, rectangle.Bottom - r));
1077             gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Bottom - l, l, l), 0F, 90F);
1078 
1079             gp.AddLine(new Point(rectangle.Right - r, rectangle.Bottom), new Point(rectangle.X + r, rectangle.Bottom));
1080             gp.AddArc(new Rectangle(rectangle.X, rectangle.Bottom - l, l, l), 90F, 90F);
1081 
1082             gp.AddLine(new Point(rectangle.X, rectangle.Bottom - r), new Point(rectangle.X, rectangle.Y + r));
1083             gp.AddArc(new Rectangle(rectangle.X, rectangle.Y, l, l), 180F, 90F);
1084             return gp;
1085         }
1086         #endregion
1087 
1088         #region 柔化
1089         ///<summary>
1090         /// 柔化
1091         /// </summary>
1092         /// <param name="b">原始图</param>
1093         /// <returns>输出图</returns>
1094         public static Bitmap KiBlur(Bitmap b)
1095         {
1096 
1097             if (b == null)
1098             {
1099                 return null;
1100             }
1101 
1102             int w = b.Width;
1103             int h = b.Height;
1104 
1105             try
1106             {
1107 
1108                 Bitmap bmpRtn = new Bitmap(w, h, PixelFormat.Format24bppRgb);
1109 
1110                 BitmapData srcData = b.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
1111                 BitmapData dstData = bmpRtn.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
1112 
1113                 unsafe
1114                 {
1115                     byte* pIn = (byte*)srcData.Scan0.ToPointer();
1116                     byte* pOut = (byte*)dstData.Scan0.ToPointer();
1117                     int stride = srcData.Stride;
1118                     byte* p;
1119 
1120                     for (int y = 0; y < h; y++)
1121                     {
1122                         for (int x = 0; x < w; x++)
1123                         {
1124                             //取周围9点的值
1125                             if (x == 0 || x == w - 1 || y == 0 || y == h - 1)
1126                             {
1127                                 //不做
1128                                 pOut[0] = pIn[0];
1129                                 pOut[1] = pIn[1];
1130                                 pOut[2] = pIn[2];
1131                             }
1132                             else
1133                             {
1134                                 int r1, r2, r3, r4, r5, r6, r7, r8, r9;
1135                                 int g1, g2, g3, g4, g5, g6, g7, g8, g9;
1136                                 int b1, b2, b3, b4, b5, b6, b7, b8, b9;
1137 
1138                                 float vR, vG, vB;
1139 
1140                                 //左上
1141                                 p = pIn - stride - 3;
1142                                 r1 = p[2];
1143                                 g1 = p[1];
1144                                 b1 = p[0];
1145 
1146                                 //正上
1147                                 p = pIn - stride;
1148                                 r2 = p[2];
1149                                 g2 = p[1];
1150                                 b2 = p[0];
1151 
1152                                 //右上
1153                                 p = pIn - stride + 3;
1154                                 r3 = p[2];
1155                                 g3 = p[1];
1156                                 b3 = p[0];
1157 
1158                                 //左侧
1159                                 p = pIn - 3;
1160                                 r4 = p[2];
1161                                 g4 = p[1];
1162                                 b4 = p[0];
1163 
1164                                 //右侧
1165                                 p = pIn + 3;
1166                                 r5 = p[2];
1167                                 g5 = p[1];
1168                                 b5 = p[0];
1169 
1170                                 //右下
1171                                 p = pIn + stride - 3;
1172                                 r6 = p[2];
1173                                 g6 = p[1];
1174                                 b6 = p[0];
1175 
1176                                 //正下
1177                                 p = pIn + stride;
1178                                 r7 = p[2];
1179                                 g7 = p[1];
1180                                 b7 = p[0];
1181 
1182                                 //右下
1183                                 p = pIn + stride + 3;
1184                                 r8 = p[2];
1185                                 g8 = p[1];
1186                                 b8 = p[0];
1187 
1188                                 //自己
1189                                 p = pIn;
1190                                 r9 = p[2];
1191                                 g9 = p[1];
1192                                 b9 = p[0];
1193 
1194                                 vR = (float)(r1 + r2 + r3 + r4 + r5 + r6 + r7 + r8 + r9);
1195                                 vG = (float)(g1 + g2 + g3 + g4 + g5 + g6 + g7 + g8 + g9);
1196                                 vB = (float)(b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8 + b9);
1197 
1198                                 vR /= 9;
1199                                 vG /= 9;
1200                                 vB /= 9;
1201 
1202                                 pOut[0] = (byte)vB;
1203                                 pOut[1] = (byte)vG;
1204                                 pOut[2] = (byte)vR;
1205 
1206                             }
1207 
1208                             pIn += 3;
1209                             pOut += 3;
1210                         }// end of x
1211 
1212                         pIn += srcData.Stride - w * 3;
1213                         pOut += srcData.Stride - w * 3;
1214                     } // end of y
1215                 }
1216 
1217                 b.UnlockBits(srcData);
1218                 bmpRtn.UnlockBits(dstData);
1219 
1220                 return bmpRtn;
1221             }
1222             catch
1223             {
1224                 return null;
1225             }
1226 
1227         } // end of KiBlur
1228         #endregion
1229 
1230         #region 滤镜
1231         /// <summary>
1232         /// 红色滤镜
1233         /// </summary>
1234         /// <param name="bitmap">Bitmap</param>
1235         /// <param name="threshold">阀值 -255~255</param>
1236         /// <returns></returns>
1237         public System.Drawing.Bitmap AdjustToRed(System.Drawing.Bitmap bitmap, int threshold)
1238         {
1239             for (int y = 0; y < bitmap.Height; y++)
1240             {
1241                 for (int x = 0; x < bitmap.Width; x++)
1242                 {
1243                     // 取得每一個 pixel
1244                     var pixel = bitmap.GetPixel(x, y);
1245                     var pR = pixel.R + threshold;
1246                     pR = Math.Max(pR, 0);
1247                     pR = Math.Min(255, pR);
1248                     // 將改過的 RGB 寫回
1249                     // 只寫入紅色的值 , G B 都放零
1250                     System.Drawing.Color newColor = System.Drawing.Color.FromArgb(pixel.A, pR, 0, 0);
1251                     bitmap.SetPixel(x, y, newColor);
1252                 }
1253             }
1254             // 回傳結果
1255             return bitmap;
1256         }
1257 
1258         /// <summary>
1259         /// 绿色滤镜
1260         /// </summary>
1261         /// <param name="bitmap">一个图片实例</param>
1262         /// <param name="threshold">阀值 -255~+255</param>
1263         /// <returns></returns>
1264         public System.Drawing.Bitmap AdjustToGreen(System.Drawing.Bitmap bitmap, int threshold)
1265         {
1266             for (int y = 0; y < bitmap.Height; y++)
1267             {
1268                 for (int x = 0; x < bitmap.Width; x++)
1269                 {
1270                     // 取得每一個 pixel
1271                     var pixel = bitmap.GetPixel(x, y);
1272                     //判斷是否超過255 如果超過就是255
1273                     var pG = pixel.G + threshold;
1274                     //如果小於0就為0
1275                     if (pG > 255) pG = 255;
1276                     if (pG < 0) pG = 0;
1277                     // 將改過的 RGB 寫回
1278                     // 只寫入綠色的值 , R B 都放零
1279                     System.Drawing.Color newColor = System.Drawing.Color.FromArgb(pixel.A, 0, pG, 0);
1280                     bitmap.SetPixel(x, y, newColor);
1281                 }
1282             }
1283             // 回傳結果
1284             return bitmap;
1285         }
1286         /// <summary>
1287         /// 蓝色滤镜
1288         /// </summary>
1289         /// <param name="bitmap">一个图片实例</param>
1290         /// <param name="threshold">阀值 -255~255</param>
1291         /// <returns></returns>
1292         public System.Drawing.Bitmap AdjustToBlue(System.Drawing.Bitmap bitmap, int threshold)
1293         {
1294             for (int y = 0; y < bitmap.Height; y++)
1295             {
1296                 for (int x = 0; x < bitmap.Width; x++)
1297                 {
1298                     // 取得每一個 pixel
1299                     var pixel = bitmap.GetPixel(x, y);
1300                     //判斷是否超過255 如果超過就是255
1301                     var pB = pixel.B + threshold;
1302                     //如果小於0就為0
1303                     if (pB > 255) pB = 255;
1304                     if (pB < 0) pB = 0;
1305                     // 將改過的 RGB 寫回
1306                     // 只寫入藍色的值 , R G 都放零
1307                     System.Drawing.Color newColor = System.Drawing.Color.FromArgb(pixel.A, 0, 0, pB);
1308                     bitmap.SetPixel(x, y, newColor);
1309                 }
1310             }
1311             // 回傳結果
1312             return bitmap;
1313         }
1314         /// <summary>
1315         /// 调整 RGB 色调
1316         /// </summary>
1317         /// <param name="bitmap"></param>
1318         /// <param name="thresholdRed">红色阀值</param>
1319         /// <param name="thresholdBlue">蓝色阀值</param>
1320         /// <param name="thresholdGreen">绿色阀值</param>
1321         /// <returns></returns>
1322         public System.Drawing.Bitmap AdjustToCustomColor(System.Drawing.Bitmap bitmap, int thresholdRed, int thresholdGreen, int thresholdBlue)
1323         {
1324             for (int y = 0; y < bitmap.Height; y++)
1325             {
1326                 for (int x = 0; x < bitmap.Width; x++)
1327                 {
1328                     // 取得每一個 pixel
1329                     var pixel = bitmap.GetPixel(x, y);
1330                     //判斷是否超過255 如果超過就是255
1331                     var pG = pixel.G + thresholdGreen;
1332                     //如果小於0就為0
1333                     if (pG > 255) pG = 255;
1334                     if (pG < 0) pG = 0;
1335                     //判斷是否超過255 如果超過就是255
1336                     var pR = pixel.R + thresholdRed;
1337                     //如果小於0就為0
1338                     if (pR > 255) pR = 255;
1339                     if (pR < 0) pR = 0;
1340                     //判斷是否超過255 如果超過就是255
1341                     var pB = pixel.B + thresholdBlue;
1342                     //如果小於0就為0
1343                     if (pB > 255) pB = 255;
1344                     if (pB < 0) pB = 0;
1345                     // 將改過的 RGB 寫回
1346                     // 只寫入綠色的值 , R B 都放零
1347                     System.Drawing.Color newColor = System.Drawing.Color.FromArgb(pixel.A, pR, pG, pB);
1348                     bitmap.SetPixel(x, y, newColor);
1349                 }
1350             }
1351             return bitmap;
1352         }
1353         #endregion
1354 
1355         #region 图片去色(图片黑白化)
1356         /// <summary>
1357         /// 图片去色(图片黑白化)
1358         /// </summary>
1359         /// <param name="original">一个需要处理的图片</param>
1360         /// <returns></returns>
1361         public static Bitmap MakeGrayscale(Bitmap original)
1362         {
1363             //create a blank bitmap the same size as original
1364             Bitmap newBitmap = new Bitmap(original.Width, original.Height);
1365 
1366             //get a graphics object from the new image
1367             Graphics g = Graphics.FromImage(newBitmap);
1368             g.SmoothingMode = SmoothingMode.HighQuality;
1369             //create the grayscale ColorMatrix
1370             ColorMatrix colorMatrix = new ColorMatrix(new float[][]
1371                           {
1372                              new float[] {.3f, .3f, .3f, 0, 0},
1373                              new float[] {.59f, .59f, .59f, 0, 0},
1374                              new float[] {.11f, .11f, .11f, 0, 0},
1375                              new float[] {0, 0, 0, 1, 0},
1376                              new float[] {0, 0, 0, 0, 1}
1377                           });
1378 
1379             //create some image attributes
1380             ImageAttributes attributes = new ImageAttributes();
1381 
1382             //set the color matrix attribute
1383             attributes.SetColorMatrix(colorMatrix);
1384 
1385             //draw the original image on the new image
1386             //using the grayscale color matrix
1387             g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
1388                0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);
1389 
1390             //dispose the Graphics object
1391             g.Dispose();
1392             return newBitmap;
1393         }
1394         #endregion
1395 
1396         #region 增加或減少亮度
1397         /// <summary>
1398         /// 增加或減少亮度
1399         /// </summary>
1400         /// <param name="img">System.Drawing.Image Source </param>
1401         /// <param name="valBrightness">0~255</param>
1402         /// <returns></returns>
1403         public System.Drawing.Bitmap AdjustBrightness(System.Drawing.Image img, int valBrightness)
1404         {
1405             // 讀入欲轉換的圖片並轉成為 Bitmap
1406             System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(img);
1407 
1408             for (int y = 0; y < bitmap.Height; y++)
1409             {
1410                 for (int x = 0; x < bitmap.Width; x++)
1411                 {
1412                     // 取得每一個 pixel
1413                     var pixel = bitmap.GetPixel(x, y);
1414 
1415                     // 判斷 如果處理過後 255 就設定為 255 如果小於則設定為 0
1416                     var pR = ((pixel.R + valBrightness > 255) ? 255 : pixel.R + valBrightness) < 0 ? 0 : ((pixel.R + valBrightness > 255) ? 255 : pixel.R + valBrightness);
1417                     var pG = ((pixel.G + valBrightness > 255) ? 255 : pixel.G + valBrightness) < 0 ? 0 : ((pixel.G + valBrightness > 255) ? 255 : pixel.G + valBrightness);
1418                     var pB = ((pixel.B + valBrightness > 255) ? 255 : pixel.B + valBrightness) < 0 ? 0 : ((pixel.B + valBrightness > 255) ? 255 : pixel.B + valBrightness);
1419 
1420                     // 將改過的 RGB 寫回
1421                     System.Drawing.Color newColor = System.Drawing.Color.FromArgb(pixel.A, pR, pG, pB);
1422 
1423                     bitmap.SetPixel(x, y, newColor);
1424 
1425                 }
1426             }
1427             // 回傳結果
1428             return bitmap;
1429         }
1430         #endregion
1431 
1432         #region 浮雕效果
1433         /// <summary>
1434         /// 浮雕效果
1435         /// </summary>
1436         /// <param name="src">一个图片实例</param>
1437         /// <returns></returns>
1438         public Bitmap AdjustToStone(Bitmap src)
1439         {
1440             // 依照 Format24bppRgb 每三个表示一 Pixel 0: 蓝 1: 绿 2: 红
1441             BitmapData bitmapData = src.LockBits(new Rectangle(0, 0, src.Width, src.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
1442 
1443             unsafe
1444             {
1445                 // 抓住第一个 Pixel 第一个数值
1446                 byte* p = (byte*)(void*)bitmapData.Scan0;
1447 
1448                 // 跨步值 - 宽度 *3 可以算出畸零地 之后跳到下一行
1449                 int nOffset = bitmapData.Stride - src.Width * 3;
1450 
1451                 for (int y = 0; y < src.Height; ++y)
1452                 {
1453                     for (int x = 0; x < src.Width; ++x)
1454                     {
1455                         // 为了理解方便 所以特地在命名
1456                         int r, g, b;
1457                         // 先取得下一个 Pixel
1458                         var q = p + 3;
1459                         r = Math.Abs(p[2] - q[2] + 128);
1460                         r = r < 0 ? 0 : r;
1461                         r = r > 255 ? 255 : r;
1462                         p[2] = (byte)r;
1463 
1464                         g = Math.Abs(p[1] - q[1] + 128);
1465                         g = g < 0 ? 0 : g;
1466                         g = g > 255 ? 255 : g;
1467                         p[1] = (byte)g;
1468 
1469                         b = Math.Abs(p[0] - q[0] + 128);
1470                         b = b < 0 ? 0 : b;
1471                         b = b > 255 ? 255 : b;
1472                         p[0] = (byte)b;
1473 
1474                         // 跳去下一个 Pixel
1475                         p += 3;
1476 
1477                     }
1478                     // 跨越畸零地
1479                     p += nOffset;
1480                 }
1481             }
1482             src.UnlockBits(bitmapData);
1483             return src;
1484         }
1485         #endregion
1486 
1487         #region 水波纹效果
1488         /// <summary>
1489         /// 水波纹效果
1490         /// </summary>
1491         /// <param name="src"></param>
1492         /// <param name="nWave">坡度</param>
1493         /// www.it165.net
1494         /// <returns></returns>
1495         public Bitmap AdjustRippleEffect(Bitmap src, short nWave)
1496         {
1497 
1498             int nWidth = src.Width;
1499             int nHeight = src.Height;
1500 
1501             // 透过公式进行水波纹的採样
1502 
1503             PointF[,] fp = new PointF[nWidth, nHeight];
1504 
1505             Point[,] pt = new Point[nWidth, nHeight];
1506 
1507             Point mid = new Point();
1508             mid.X = nWidth / 2;
1509             mid.Y = nHeight / 2;
1510 
1511             double newX, newY;
1512             double xo, yo;
1513 
1514             //先取样将水波纹座标跟RGB取出
1515             for (int x = 0; x < nWidth; ++x)
1516                 for (int y = 0; y < nHeight; ++y)
1517                 {
1518                     xo = ((double)nWave * Math.Sin(2.0 * 3.1415 * (float)y / 128.0));
1519                     yo = ((double)nWave * Math.Cos(2.0 * 3.1415 * (float)x / 128.0));
1520 
1521                     newX = (x + xo);
1522                     newY = (y + yo);
1523 
1524                     if (newX > 0 && newX < nWidth)
1525                     {
1526                         fp[x, y].X = (float)newX;
1527                         pt[x, y].X = (int)newX;
1528                     }
1529                     else
1530                     {
1531                         fp[x, y].X = (float)0.0;
1532                         pt[x, y].X = 0;
1533                     }
1534 
1535 
1536                     if (newY > 0 && newY < nHeight)
1537                     {
1538                         fp[x, y].Y = (float)newY;
1539                         pt[x, y].Y = (int)newY;
1540                     }
1541                     else
1542                     {
1543                         fp[x, y].Y = (float)0.0;
1544                         pt[x, y].Y = 0;
1545                     }
1546                 }
1547 
1548 
1549             //进行合成
1550             Bitmap bSrc = (Bitmap)src.Clone();
1551 
1552             // 依照 Format24bppRgb 每三个表示一 Pixel 0: 蓝 1: 绿 2: 红
1553             BitmapData bitmapData = src.LockBits(new Rectangle(0, 0, src.Width, src.Height), ImageLockMode.ReadWrite,
1554                                            PixelFormat.Format24bppRgb);
1555             BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite,
1556                                              PixelFormat.Format24bppRgb);
1557 
1558             int scanline = bitmapData.Stride;
1559 
1560             IntPtr Scan0 = bitmapData.Scan0;
1561             IntPtr SrcScan0 = bmSrc.Scan0;
1562 
1563             unsafe
1564             {
1565                 byte* p = (byte*)(void*)Scan0;
1566                 byte* pSrc = (byte*)(void*)SrcScan0;
1567 
1568                 int nOffset = bitmapData.Stride - src.Width * 3;
1569 
1570                 int xOffset, yOffset;
1571 
1572                 for (int y = 0; y < nHeight; ++y)
1573                 {
1574                     for (int x = 0; x < nWidth; ++x)
1575                     {
1576                         xOffset = pt[x, y].X;
1577                         yOffset = pt[x, y].Y;
1578 
1579                         if (yOffset >= 0 && yOffset < nHeight && xOffset >= 0 && xOffset < nWidth)
1580                         {
1581                             p[0] = pSrc[(yOffset * scanline) + (xOffset * 3)];
1582                             p[1] = pSrc[(yOffset * scanline) + (xOffset * 3) + 1];
1583                             p[2] = pSrc[(yOffset * scanline) + (xOffset * 3) + 2];
1584                         }
1585 
1586                         p += 3;
1587                     }
1588                     p += nOffset;
1589                 }
1590             }
1591 
1592             src.UnlockBits(bitmapData);
1593             bSrc.UnlockBits(bmSrc);
1594 
1595             return src;
1596         }
1597         #endregion
1598 
1599         #region 调整曝光度值
1600         /// <summary>
1601         /// 调整曝光度值
1602         /// </summary>
1603         /// <param name="src">原图</param>
1604         /// <param name="r"></param>
1605         /// <param name="g"></param>
1606         /// <param name="b"></param>
1607         /// <returns></returns>
1608         public Bitmap AdjustGamma(Bitmap src, double r, double g, double b)
1609         {
1610             // 判断是不是在0.2~5 之间
1611             r = Math.Min(Math.Max(0.2, r), 5);
1612             g = Math.Min(Math.Max(0.2, g), 5);
1613             b = Math.Min(Math.Max(0.2, b), 5);
1614 
1615             // 依照 Format24bppRgb 每三个表示一 Pixel 0: 蓝 1: 绿 2: 红
1616             BitmapData bitmapData = src.LockBits(new Rectangle(0, 0, src.Width, src.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
1617 
1618             unsafe
1619             {
1620                 // 抓住第一个 Pixel 第一个数值
1621                 byte* p = (byte*)(void*)bitmapData.Scan0;
1622 
1623                 // 跨步值 - 宽度 *3 可以算出畸零地 之后跳到下一行
1624                 int nOffset = bitmapData.Stride - src.Width * 3;
1625 
1626                 for (int y = 0; y < src.Height; y++)
1627                 {
1628                     for (int x = 0; x < src.Width; x++)
1629                     {
1630                         p[2] = (byte)Math.Min(255, (int)((255.0 * Math.Pow(p[2] / 255.0, 1.0 / r)) + 0.5));
1631                         p[1] = (byte)Math.Min(255, (int)((255.0 * Math.Pow(p[1] / 255.0, 1.0 / g)) + 0.5));
1632                         p[0] = (byte)Math.Min(255, (int)((255.0 * Math.Pow(p[0] / 255.0, 1.0 / b)) + 0.5));
1633 
1634 
1635                         // 跳去下一个 Pixel
1636                         p += 3;
1637 
1638                     }
1639                     // 跨越畸零地
1640                     p += nOffset;
1641                 }
1642             }
1643             src.UnlockBits(bitmapData);
1644             return src;
1645 
1646         }
1647         #endregion
1648 
1649         #region 高对比,对过深的颜色调浅,过浅的颜色调深。
1650         /// <summary>
1651         /// 高对比,对过深的颜色调浅,过浅的颜色调深。
1652         /// </summary>
1653         /// <param name="src"></param>
1654         /// <param name="effectThreshold"> 高对比程度 -100~100</param>
1655         /// <returns></returns>
1656         public Bitmap Contrast(Bitmap src, float effectThreshold)
1657         {
1658 
1659             // 依照 Format24bppRgb 每三个表示一 Pixel 0: 蓝 1: 绿 2: 红
1660             BitmapData bitmapData = src.LockBits(new Rectangle(0, 0, src.Width, src.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
1661 
1662             // 判断是否在 -100~100
1663             effectThreshold = effectThreshold < -100 ? -100 : effectThreshold;
1664             effectThreshold = effectThreshold > 100 ? 100 : effectThreshold;
1665 
1666             effectThreshold = (float)((100.0 + effectThreshold) / 100.0);
1667             effectThreshold *= effectThreshold;
1668 
1669             unsafe
1670             {
1671                 // 抓住第一个 Pixel 第一个数值 www.it165.net
1672                 byte* p = (byte*)(void*)bitmapData.Scan0;
1673 
1674                 // 跨步值 - 宽度 *3 可以算出畸零地 之后跳到下一行
1675                 int nOffset = bitmapData.Stride - src.Width * 3;
1676 
1677 
1678 
1679                 for (int y = 0; y < src.Height; y++)
1680                 {
1681                     for (int x = 0; x < src.Width; x++)
1682                     {
1683                         double buffer = 0;
1684 
1685 
1686                         // 公式  (Red/255)-0.5= 偏离中间值程度
1687                         // ((偏离中间值程度 * 影响范围)+0.4 ) * 255
1688                         buffer = ((((p[2] / 255.0) - 0.5) * effectThreshold) + 0.5) * 255.0;
1689                         buffer = buffer > 255 ? 255 : buffer;
1690                         buffer = buffer < 0 ? 0 : buffer;
1691                         p[2] = (byte)buffer;
1692 
1693                         buffer = ((((p[1] / 255.0) - 0.5) * effectThreshold) + 0.5) * 255.0;
1694                         buffer = buffer > 255 ? 255 : buffer;
1695                         buffer = buffer < 0 ? 0 : buffer;
1696                         p[1] = (byte)buffer;
1697 
1698 
1699                         buffer = ((((p[0] / 255.0) - 0.5) * effectThreshold) + 0.5) * 255.0;
1700                         buffer = buffer > 255 ? 255 : buffer;
1701                         buffer = buffer < 0 ? 0 : buffer;
1702                         p[0] = (byte)buffer;
1703 
1704 
1705 
1706 
1707                         // 跳去下一个 Pixel
1708                         p += 3;
1709 
1710                     }
1711                     // 跨越畸零地
1712                     p += nOffset;
1713                 }
1714             }
1715             src.UnlockBits(bitmapData);
1716             return src;
1717 
1718 
1719         }
1720         #endregion
1721 
1722         #region 对图片进行雾化效果
1723         /// <summary>
1724         /// 对图片进行雾化效果
1725         /// </summary>
1726         /// <param name="bmp"></param>
1727         /// <returns></returns>
1728         public Bitmap Atomization(Bitmap bmp)
1729         {
1730 
1731             int Height = bmp.Height;
1732             int Width = bmp.Width;
1733             Bitmap newBitmap = new Bitmap(Width, Height);
1734             Bitmap oldBitmap = bmp;
1735             Color pixel;
1736             for (int x = 1; x < Width - 1; x++)
1737             {
1738                 for (int y = 1; y < Height - 1; y++)
1739                 {
1740                     Random MyRandom = new Random(Guid.NewGuid().GetHashCode());
1741                     int k = MyRandom.Next(123456);
1742                     //像素块大小
1743                     int dx = x + k % 19;
1744                     int dy = y + k % 19;
1745                     if (dx >= Width)
1746                         dx = Width - 1;
1747                     if (dy >= Height)
1748                         dy = Height - 1;
1749                     pixel = oldBitmap.GetPixel(dx, dy);
1750                     newBitmap.SetPixel(x, y, pixel);
1751                 }
1752             }
1753             return newBitmap;
1754         }
1755         #endregion 
1756     
1757 
1758     } //END Class DrawValidationCode
1759     #endregion
1760 
1761     #region 高斯模糊算法
1762     /// <summary>
1763     /// 高斯模糊算法
1764     /// </summary>
1765     public class Gaussian
1766     {
1767         public static double[,] Calculate1DSampleKernel(double deviation, int size)
1768         {
1769             double[,] ret = new double[size, 1];
1770             double sum = 0;
1771             int half = size / 2;
1772             for (int i = 0; i < size; i++)
1773             {
1774                 ret[i, 0] = 1 / (Math.Sqrt(2 * Math.PI) * deviation) * Math.Exp(-(i - half) * (i - half) / (2 * deviation * deviation));
1775                 sum += ret[i, 0];
1776             }
1777             return ret;
1778         }
1779         public static double[,] Calculate1DSampleKernel(double deviation)
1780         {
1781             int size = (int)Math.Ceiling(deviation * 3) * 2 + 1;
1782             return Calculate1DSampleKernel(deviation, size);
1783         }
1784         public static double[,] CalculateNormalized1DSampleKernel(double deviation)
1785         {
1786             return NormalizeMatrix(Calculate1DSampleKernel(deviation));
1787         }
1788         public static double[,] NormalizeMatrix(double[,] matrix)
1789         {
1790             double[,] ret = new double[matrix.GetLength(0), matrix.GetLength(1)];
1791             double sum = 0;
1792             for (int i = 0; i < ret.GetLength(0); i++)
1793             {
1794                 for (int j = 0; j < ret.GetLength(1); j++)
1795                     sum += matrix[i, j];
1796             }
1797             if (sum != 0)
1798             {
1799                 for (int i = 0; i < ret.GetLength(0); i++)
1800                 {
1801                     for (int j = 0; j < ret.GetLength(1); j++)
1802                         ret[i, j] = matrix[i, j] / sum;
1803                 }
1804             }
1805             return ret;
1806         }
1807         public static double[,] GaussianConvolution(double[,] matrix, double deviation)
1808         {
1809             double[,] kernel = CalculateNormalized1DSampleKernel(deviation);
1810             double[,] res1 = new double[matrix.GetLength(0), matrix.GetLength(1)];
1811             double[,] res2 = new double[matrix.GetLength(0), matrix.GetLength(1)];
1812             //x-direction
1813             for (int i = 0; i < matrix.GetLength(0); i++)
1814             {
1815                 for (int j = 0; j < matrix.GetLength(1); j++)
1816                     res1[i, j] = processPoint(matrix, i, j, kernel, 0);
1817             }
1818             //y-direction
1819             for (int i = 0; i < matrix.GetLength(0); i++)
1820             {
1821                 for (int j = 0; j < matrix.GetLength(1); j++)
1822                     res2[i, j] = processPoint(res1, i, j, kernel, 1);
1823             }
1824             return res2;
1825         }
1826         private static double processPoint(double[,] matrix, int x, int y, double[,] kernel, int direction)
1827         {
1828             double res = 0;
1829             int half = kernel.GetLength(0) / 2;
1830             for (int i = 0; i < kernel.GetLength(0); i++)
1831             {
1832                 int cox = direction == 0 ? x + i - half : x;
1833                 int coy = direction == 1 ? y + i - half : y;
1834                 if (cox >= 0 && cox < matrix.GetLength(0) && coy >= 0 && coy < matrix.GetLength(1))
1835                 {
1836                     res += matrix[cox, coy] * kernel[i, 0];
1837                 }
1838             }
1839             return res;
1840         }
1841         /// <summary>
1842         /// 对颜色值进行灰色处理
1843         /// </summary>
1844         /// <param name="cr"></param>
1845         /// <returns></returns>
1846         private Color grayscale(Color cr)
1847         {
1848             return Color.FromArgb(cr.A, (int)(cr.R * .3 + cr.G * .59 + cr.B * 0.11),
1849                (int)(cr.R * .3 + cr.G * .59 + cr.B * 0.11),
1850               (int)(cr.R * .3 + cr.G * .59 + cr.B * 0.11));
1851         }
1852         /// <summary>
1853         /// 对图片进行高斯模糊
1854         /// </summary>
1855         /// <param name="d">模糊数值,数值越大模糊越很</param>
1856         /// <param name="image">一个需要处理的图片</param>
1857         /// <returns></returns>
1858         public Bitmap FilterProcessImage(double d, Bitmap image)
1859         {
1860             Bitmap ret = new Bitmap(image.Width, image.Height);
1861             Double[,] matrixR = new Double[image.Width, image.Height];
1862             Double[,] matrixG = new Double[image.Width, image.Height];
1863             Double[,] matrixB = new Double[image.Width, image.Height];
1864             for (int i = 0; i < image.Width; i++)
1865             {
1866                 for (int j = 0; j < image.Height; j++)
1867                 {
1868                     //matrix[i, j] = grayscale(image.GetPixel(i, j)).R;
1869                     matrixR[i, j] = image.GetPixel(i, j).R;
1870                     matrixG[i, j] = image.GetPixel(i, j).G;
1871                     matrixB[i, j] = image.GetPixel(i, j).B;
1872                 }
1873             }
1874             matrixR = Gaussian.GaussianConvolution(matrixR, d);
1875             matrixG = Gaussian.GaussianConvolution(matrixG, d);
1876             matrixB = Gaussian.GaussianConvolution(matrixB, d);
1877             for (int i = 0; i < image.Width; i++)
1878             {
1879                 for (int j = 0; j < image.Height; j++)
1880                 {
1881                     Int32 R = (int)Math.Min(255, matrixR[i, j]);
1882                     Int32 G = (int)Math.Min(255, matrixG[i, j]);
1883                     Int32 B = (int)Math.Min(255, matrixB[i, j]);
1884                     ret.SetPixel(i, j, Color.FromArgb(R, G, B));
1885                 }
1886             }
1887             return ret;
1888         }
1889 
1890     }
1891     #endregion
1892 
1893 }

该代码转载自: Web(B/S)生成模糊验证码的几种方式(转载) 

 

Web(B/S)生成模糊验证码的几种方式(转载)

posted on 2018-06-28 15:15  踏歌&而行  阅读(3940)  评论(2编辑  收藏  举报