戏说 .NET GDI+系列学习教程(三、Graphics类的应用_验证码)

关于Graphics也有了基本了解下面想说的的是学这个东东干什么呢,到底如何应用
目前常见应用
1、验证码(参照网上的)
2、打印排版(会提到关于条形码大小设置)
3、自定义控件

一、验证码

  1     class ValidateCode
  2     {
  3         #region 定义和初始化配置字段
  4 
  5         //用户存取验证码字符串
  6         public string validationCode = String.Empty;
  7 
  8         //生成的验证码字符串
  9         public char[] chars = null;
 10 
 11         /// <summary>
 12         /// 获取随机验证码
 13         /// </summary>
 14         public String ValidationCode
 15         {
 16             get { return validationCode; }
 17         }
 18 
 19         /// <summary>
 20         /// 验证码字符串的长度
 21         /// </summary>
 22         private Int32 validationCodeCount = 4;
 23 
 24         /// <summary>
 25         /// 获取和设置验证码字符串的长度
 26         /// </summary>
 27         public Int32 ValidationCodeCount
 28         {
 29             get { return validationCodeCount; }
 30             set { validationCodeCount = value; }
 31         }
 32 
 33         /// <summary>
 34         /// 画板对象
 35         /// </summary>
 36         Graphics dc = null;
 37 
 38         //验证码的宽度,默认为130
 39         private int bgWidth = 130;
 40 
 41         /// <summary>
 42         /// 验证码的宽度,默认为130
 43         /// </summary>
 44         public Int32 Width
 45         {
 46             get { return bgWidth; }
 47             set { bgWidth = value; }
 48         }
 49 
 50         //验证码的宽度,默认为130
 51         private int bgHeight = 40;
 52 
 53         /// <summary>
 54         /// 验证码的高度,默认为40
 55         /// </summary>
 56         public Int32 Height
 57         {
 58             get { return bgHeight; }
 59             set { bgHeight = value; }
 60         }
 61 
 62         //字体大小 字体最小值
 63         private int fontMinSize = 20;
 64 
 65         /// <summary>
 66         /// 验证码字体的最小值,默认为20,建议不小于15像素
 67         /// </summary>
 68         public Int32 FontMinSize
 69         {
 70             get { return fontMinSize; }
 71             set { fontMinSize = value; }
 72         }
 73         //字体大小 字体最大值
 74         private Int32 fontMaxSize = 25;
 75 
 76         /// <summary>
 77         /// 验证码字体的最大值,默认为25
 78         /// </summary>
 79         public Int32 FontMaxSize
 80         {
 81             get { return fontMaxSize; }
 82             set { fontMaxSize = value; }
 83         }
 84 
 85         //验证码字体的颜色
 86         private Color[] fontColor = { };
 87 
 88         /// <summary>
 89         /// 验证码字体的颜色,默认为系统自动生成字体颜色
 90         /// </summary>
 91         public Color[] FontColor
 92         {
 93             get { return fontColor; }
 94             set { fontColor = value; }
 95         }
 96 
 97         private Color backColor = Color.FromArgb(243, 255, 255);
 98 
 99         /// <summary>
100         /// 验证码的背景色,默认为Color.FromArgb(243, 251, 254)
101         /// </summary>
102         public Color BackgroundColor
103         {
104             get { return backColor; }
105             set { backColor = value; }
106         }
107 
108         //贝塞尔曲线的条数,默认为3条
109         private Int32 bezierCount = 3;
110 
111         /// <summary>
112         /// 贝塞尔曲线的条数,默认为3条
113         /// </summary>
114         public Int32 BezierCount
115         {
116             get { return bezierCount; }
117             set { bezierCount = value; }
118         }
119 
120         //直线条数,默认为3条
121         private Int32 lineCount = 3;
122 
123         /// <summary>
124         /// 直线条数,默认为3条
125         /// </summary>
126         public Int32 LineCount
127         {
128             get { return lineCount; }
129             set { lineCount = value; }
130         }
131 
132         //随机字符串列表
133         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; 
134 
135         /// <summary>
136         /// 随机字符串列表,请使用英文状态下的逗号分隔
137         /// </summary>
138         public String CharCollection
139         {
140             get { return charCollection; }
141             set { charCollection = value; }
142         }
143 
144         //验证码字符串个数,默认为4个字符
145         private Int32 intCount = 4;
146 
147         /// <summary>
148         /// 验证码字符串个数,默认为4个字符
149         /// </summary>
150         public Int32 IntCount
151         {
152             get { return intCount; }
153             set { intCount = value; }
154         }
155 
156         //是否添加噪点,默认添加,噪点颜色为系统随机生成。
157         private Boolean isPixel = true;
158         /// <summary>
159         /// 是否添加噪点,默认添加,噪点颜色为系统随机生成。
160         /// </summary>
161         public Boolean IsPixel
162         {
163             get { return isPixel; }
164             set { isPixel = value; }
165         }
166 
167         //是否添加随机噪点字符串,默认添加
168         private Boolean isRandString = true;
169         /// <summary>
170         /// 是否添加随机噪点字符串,默认添加
171         /// </summary>
172         public Boolean IsRandString
173         {
174             get { return isRandString; }
175             set { isRandString = value; }
176         }
177 
178         /// <summary>
179         /// 随机背景字符串的个数
180         /// </summary>
181         public Int32 RandomStringCount
182         {
183             get; set;
184         }
185 
186         //随机背景字符串的大小
187         private Int32 randomStringFontSize = 9;
188         /// <summary>
189         /// 随机背景字符串的大小
190         /// </summary>
191         public Int32 RandomStringFontSize
192         {
193             get { return randomStringFontSize; }
194             set { randomStringFontSize = value; }
195         }
196 
197         /// <summary>
198         /// 是否对图片进行扭曲
199         /// </summary>
200         public Boolean IsTwist
201         {
202             get; set;
203         }
204 
205         /// <summary>
206         /// 边框样式
207         /// </summary>
208         public enum BorderStyle
209         {
210             /// <summary>
211             /// 无边框
212             /// </summary>
213             None,
214             /// <summary>
215             /// 矩形边框
216             /// </summary>
217             Rectangle,
218             /// <summary>
219             /// 圆角边框
220             /// </summary>
221             RoundRectangle
222         }
223 
224         /// <summary>
225         /// 验证码字符串随机转动的角度 默认40
226         /// </summary>
227         private Int32 rotationAngle = 40;
228         /// <summary>
229         /// 验证码字符串随机转动的角度的最大值
230         /// </summary>
231         public Int32 RotationAngle
232         {
233             get { return rotationAngle; }
234             set { rotationAngle = value; }
235         }
236 
237         /// <summary>
238         /// 设置或获取边框样式
239         /// </summary>
240         public BorderStyle Border
241         {
242             get; set;
243         }
244 
245         /// <summary>
246         /// 对验证码图片进行高斯模糊的阀值,如果设置为0
247         /// </summary>
248         private Double gaussianDeviation = 0;
249 
250         /// <summary>
251         /// 对验证码图片进行高斯模糊的阀值,如果设置为0,则不对图片进行高斯模糊,该设置可能会对图片处理的性能有较大影响
252         /// </summary>
253         public Double GaussianDeviation
254         {
255             get { return gaussianDeviation; }
256             set { gaussianDeviation = value; }
257         }
258         private Int32 brightnessValue = 0;
259         /// <summary>
260         /// 对图片进行暗度和亮度的调整,如果该值为0,则不调整。该设置会对图片处理性能有较大影响
261         /// </summary>
262         public Int32 BrightnessValue
263         {
264             get { return brightnessValue; }
265             set { brightnessValue = value; }
266         }
267 
268         #endregion
269 
270 
271         private Point[] strPoint = null;
272 
273         Random random = new Random();
274 
275         /// <summary>
276         /// 构造函数,用于初始化常用变量
277         /// </summary>
278         public void DrawValidationCode()
279         {
280             //随机对象 
281             //Random类所取到的系统时钟种子接近甚至完全一样
282             //解决方案:new Random(Guid.NewGuid().GetHashCode());
283             random = new Random(Guid.NewGuid().GetHashCode());
284             //坐标数组
285             strPoint = new Point[validationCodeCount + 1];
286             if (gaussianDeviation < 0)
287                 gaussianDeviation = 0;
288         }
289 
290         /// <summary>
291         /// 生成验证码
292         /// 思路:多张图片合成
293         /// 1.验证码背景图片
294         /// 1.1.背景包含
295         /// 1.1.1.背景颜色
296         /// 1.1.2.噪点
297         /// 1.1.3.干扰文字
298         /// 1.1.4.干扰线条(直线、曲线)
299         /// 2.验证码字符
300         /// 3.验证码图片扭曲
301         /// 4.验证码图片模糊
302         /// 5.验证码图片亮度
303         /// 6.验证码图片保持在内存流中
304         /// </summary>
305         /// <param name="target">用于存储图片的一般字节序列</param>
306         public MemoryStream CreateImage(string code)
307         {
308             MemoryStream target = new MemoryStream();
309             // 定义图片对象大小,
310             Bitmap bit = new Bitmap(bgWidth + 1, bgHeight + 1);
311             // 定义 Graphics(画板)根据图片对象 
312             dc = Graphics.FromImage(bit);
313             /*
314                 SmoothingModeAntiAlias      指定消除锯齿的呈现。
315                 SmoothingModeDefault        指定默认模式。
316                 SmoothingModeHighQuality    指定高质量、低速度呈现。
317                 SmoothingModeHighSpeed      指定高速度、低质量呈现。
318                 SmoothingModeInvalid        指定一个无效模式。
319                 SmoothingModeNone           指定不消除锯齿。
320             */
321             dc.SmoothingMode = SmoothingMode.HighQuality;
322             //文本的呈现模式
323             dc.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
324             // 插补模式
325             dc.InterpolationMode = InterpolationMode.HighQualityBilinear;
326             //合成图像的呈现质量
327             dc.CompositingQuality = CompositingQuality.HighQuality;
328             try
329             {
330                 //清空画板,指定背景色(白色)
331                 dc.Clear(Color.White);
332                 DrawValidationCode();
333                 //DrawImageUnscaled 在指定的位置使用图像的原始物理大小绘制指定的图像
334                 // 验证码背景
335                 dc.DrawImageUnscaled(DrawBackground(), 0, 0);
336                 // 验证码字符
337                 dc.DrawImageUnscaled(DrawRandomString(code), 0, 0);
338                 //对图片文字进行扭曲
339                 bit = AdjustRippleEffect(bit, 5);
340                 //对图片进行高斯模糊
341                 if (gaussianDeviation > 0)
342                 {
343                     Gaussian gau = new Gaussian();
344                     bit = gau.FilterProcessImage(gaussianDeviation, bit);
345                 }
346                 //进行暗度和亮度处理
347                 if (brightnessValue != 0)
348                 {
349                     //对图片进行调暗处理 
350                     bit = AdjustBrightness(bit, brightnessValue);
351                 }
352                 bit.Save(target, ImageFormat.Jpeg);
353                 //输出图片流                    
354                 return target;
355 
356             }
357             finally
358             {
359                 //brush.Dispose();        
360                 bit.Dispose();
361                 dc.Dispose();
362             }
363         }
364 
365         #region 画验证码背景,例如,增加早点,添加曲线和直线等            
366         /// <summary>
367         /// 画验证码背景,例如,增加早点,添加曲线和直线等
368         /// 1.1.背景包含
369         /// 1.1.1.背景颜色
370         /// 1.1.2.噪点
371         /// 1.1.3.干扰文字
372         /// 1.1.4.干扰线条(直线、曲线)
373         /// </summary>
374         /// <returns>Bitmap 对象</returns>
375         private Bitmap DrawBackground()
376         {
377             Bitmap bit = new Bitmap(bgWidth + 1, bgHeight + 1);
378             Graphics g = Graphics.FromImage(bit);
379             g.SmoothingMode = SmoothingMode.HighQuality;
380             g.Clear(Color.White);
381             Rectangle rectangle = new Rectangle(0, 0, bgWidth, bgHeight);
382             Brush brush = new SolidBrush(backColor);
383             //填充矩形
384             g.FillRectangle(brush, rectangle);
385             //画噪点           
386             if (isPixel)
387             {
388                 g.DrawImageUnscaled(DrawRandomPixel(30), 0, 0);
389             }
390             // 背景干扰字符
391             g.DrawImageUnscaled(DrawRandBgString(), 0, 0);
392             //画曲线              
393             //g.DrawImageUnscaled(DrawRandomBezier(bezierCount), 0, 0);
394             //画直线      
395             //g.DrawImageUnscaled(DrawRandomLine(lineCount), 0, 0);
396             if (Border == BorderStyle.Rectangle)
397             {
398                 //绘制边框            
399                 g.DrawRectangle(new Pen(Color.FromArgb(90, 87, 46)), 0, 0, bgWidth, bgHeight);
400             }
401             else if (Border == BorderStyle.RoundRectangle)
402             {
403                 //画圆角      
404                 DrawRoundRectangle(g, rectangle, Color.FromArgb(90, 87, 46), 1, 3);
405             }
406             return bit;
407         }
408         #endregion
409 
410         #region 画随机噪点
411         /// <summary>            
412         /// 画随机噪点
413         /// 在指定区域中随机设置像素点的颜色
414         /// </summary>            
415         /// <param name="pixNum">噪点的百分比</param>            
416         /// <returns></returns>           
417         public Bitmap DrawRandomPixel(Int32 pixNum)
418         {
419             Bitmap b = new Bitmap(bgWidth, bgHeight);
420             //透明化
421             b.MakeTransparent();
422             Graphics graph = Graphics.FromImage(b);
423             graph.SmoothingMode = SmoothingMode.HighQuality;
424             graph.InterpolationMode = InterpolationMode.HighQualityBilinear;
425             //画噪点                
426             for (int i = 0; i < (bgHeight * bgWidth) / pixNum; i++)
427             {
428                 int x = random.Next(b.Width);
429                 int y = random.Next(b.Height);
430                 //设置随机像素点的颜色
431                 b.SetPixel(x, y, GetRandomDeepColor());
432                 //下移坐标重新画点                    
433                 if ((x + 1) < b.Width && (y + 1) < b.Height)
434                 {
435                     //画图片的前景噪音点   
436                     graph.DrawRectangle(new Pen(Color.Silver), random.Next(b.Width), random.Next(b.Height), 1, 1);
437                 }
438             }
439             return b;
440         }
441         #endregion
442 
443         #region 画干扰背景文字    
444         /// <summary>            
445         /// 画背景干扰文字            
446         /// </summary>            
447         /// <returns></returns>           
448         private Bitmap DrawRandBgString()
449         {
450             Bitmap b = new Bitmap(bgWidth, bgHeight);
451             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" };
452             //设置透明
453             b.MakeTransparent();
454             Graphics g = Graphics.FromImage(b);
455             g.Clear(Color.Transparent);
456             g.PixelOffsetMode = PixelOffsetMode.HighQuality;
457             g.SmoothingMode = SmoothingMode.HighQuality;
458             g.TextRenderingHint = TextRenderingHint.AntiAlias;
459             g.InterpolationMode = InterpolationMode.HighQualityBilinear;
460             //设置字体显示格式         
461             StringFormat format = new StringFormat(StringFormatFlags.NoClip);
462             format.Alignment = StringAlignment.Center;
463             format.LineAlignment = StringAlignment.Center;
464             FontFamily f = new FontFamily(GenericFontFamilies.Serif);
465             Font textFont = new Font(f, randomStringFontSize, FontStyle.Underline);
466             int randAngle = 60; //随机转动角度
467             for (int i = 0; i < RandomStringCount; i++)
468             {
469                 Brush brush = new System.Drawing.SolidBrush(GetRandomLightColor());
470                 Point pot = new Point(random.Next(5, bgWidth - 5), random.Next(5, bgHeight - 5));
471                 //随机转动的度数                
472                 float angle = random.Next(-randAngle, randAngle);
473                 //转动画布                 
474                 g.RotateTransform(angle);
475                 g.DrawString(randStr[random.Next(randStr.Length)], textFont, brush, pot, format);
476                 //转回去,为下一个字符做准备
477                 g.RotateTransform(-angle);
478                 //释放资源
479                 brush.Dispose();
480             }
481             textFont.Dispose();
482             format.Dispose();
483             f.Dispose();
484             return b;
485         }
486         #endregion
487 
488         #region 随机生成贝塞尔曲线           
489         /// <summary>            
490         /// 随机生成贝塞尔曲线            
491         /// </summary>            
492         /// <param name="bmp">一个图片的实例</param>            
493         /// <param name="lineNum">线条数量</param>            
494         /// <returns></returns>       
495         public Bitmap DrawRandomBezier(Int32 lineNum)
496         {
497             Bitmap b = new Bitmap(bgWidth, bgHeight);
498             b.MakeTransparent();
499             Graphics g = Graphics.FromImage(b);
500             g.Clear(Color.Transparent);
501             g.SmoothingMode = SmoothingMode.HighQuality;
502             g.PixelOffsetMode = PixelOffsetMode.HighQuality;
503             GraphicsPath gPath1 = new GraphicsPath();
504             Int32 lineRandNum = random.Next(lineNum);
505             for (int i = 0; i < (lineNum - lineRandNum); i++)
506             {
507                 Pen p = new Pen(GetRandomDeepColor());
508                 Point[] point = {
509                     new Point(random.Next(1, (b.Width / 10)), random.Next(1, (b.Height))),
510                     new Point(random.Next((b.Width / 10) * 2, (b.Width / 10) * 4), random.Next(1, (b.Height))),
511                     new Point(random.Next((b.Width / 10) * 4, (b.Width / 10) * 6), random.Next(1, (b.Height))),
512                     new Point(random.Next((b.Width / 10) * 8, b.Width), random.Next(1, (b.Height)))
513                 };
514                 gPath1.AddBeziers(point);
515                 g.DrawPath(p, gPath1);
516                 p.Dispose();
517             }
518             for (int i = 0; i < lineRandNum; i++)
519             {
520                 Pen p = new Pen(GetRandomDeepColor());
521                 Point[] point = {
522                     new Point(random.Next(1, b.Width), random.Next(1, b.Height)),
523                     new Point(random.Next((b.Width / 10) * 2, b.Width), random.Next(1, b.Height)),
524                     new Point(random.Next((b.Width / 10) * 4, b.Width), random.Next(1, b.Height)),
525                     new Point(random.Next(1, b.Width), random.Next(1, b.Height))
526                 };
527                 gPath1.AddBeziers(point);
528                 g.DrawPath(p, gPath1);
529                 p.Dispose();
530             }
531             return b;
532         }
533         #endregion
534 
535         #region 画直线            
536         /// <summary>            
537         /// 画直线            
538         /// </summary>            
539         /// <param name="bmp">一个bmp实例</param>            
540         /// <param name="lineNum">线条个数</param>            
541         /// <returns></returns>           
542         public Bitmap DrawRandomLine(Int32 lineNum)
543         {
544             if (lineNum < 0) throw new ArgumentNullException("参数bmp为空!");
545             Bitmap b = new Bitmap(bgWidth, bgHeight);
546             b.MakeTransparent();
547             Graphics g = Graphics.FromImage(b);
548             g.Clear(Color.Transparent);
549             g.PixelOffsetMode = PixelOffsetMode.HighQuality;
550             g.SmoothingMode = SmoothingMode.HighQuality;
551             for (int i = 0; i < lineNum; i++)
552             {
553                 Pen p = new Pen(GetRandomDeepColor());
554                 Point pt1 = new Point(random.Next(1, (b.Width / 5) * 2), random.Next(b.Height));
555                 Point pt2 = new Point(random.Next((b.Width / 5) * 3, b.Width), random.Next(b.Height));
556                 g.DrawLine(p, pt1, pt2);
557                 p.Dispose();
558             }
559             return b;
560         }
561         #endregion
562 
563         #region 写入验证码的字符串            
564         /// <summary>            
565         /// 写入验证码的字符串            
566         /// </summary>            
567         private Bitmap DrawRandomString(string Code)
568         {
569             if (fontMaxSize >= (bgHeight / 5) * 4)
570                 throw new ArgumentException("字体最大值参数FontMaxSize与验证码高度相近,这会导致描绘验证码字符串时出错,请重新设置参数!");
571             Bitmap b = new Bitmap(bgWidth, bgHeight);
572             b.MakeTransparent();
573             Graphics g = Graphics.FromImage(b);
574             g.Clear(Color.Transparent);
575             g.PixelOffsetMode = PixelOffsetMode.Half;
576             g.SmoothingMode = SmoothingMode.HighQuality;
577             g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
578             g.InterpolationMode = InterpolationMode.HighQualityBilinear;
579             chars = Code.ToCharArray();            //拆散字符串成单字符数组     
580             validationCode = chars.ToString();
581             //设置字体显示格式            
582             StringFormat format = new StringFormat(StringFormatFlags.NoClip);
583             format.Alignment = StringAlignment.Center;
584             format.LineAlignment = StringAlignment.Center;
585             FontFamily f = new FontFamily(GenericFontFamilies.Monospace);
586             Int32 charNum = chars.Length;
587             Point sPoint = new Point();
588             Int32 fontSize = 12;
589             validationCodeCount = charNum;
590             for (int i = 0; i < validationCodeCount; i++)
591             {
592                 //定义字体                 
593                 Font textFont = new Font(f, random.Next(fontMinSize, fontMaxSize), FontStyle.Bold);
594                 //定义画刷,用于写字符串          
595                 //Brush brush = new SolidBrush(GetRandomDeepColor());    
596                 Int32 textFontSize = Convert.ToInt32(textFont.Size);
597                 fontSize = textFontSize;
598                 //Point point = new Point(random.Next((bgWidth / charNum) * i + 5, (bgWidth / charNum) * (i + 1)), random.Next(bgHeight / 5 + textFontSize / 2, bgHeight - textFontSize / 2));
599                 // 字符位置坐标
600                 Point point = new Point(random.Next((bgWidth / charNum) * i + 2, (bgWidth / charNum) * (i + 1) - (textFontSize / 2)), random.Next(bgHeight / 5 + textFontSize / 2, bgHeight - textFontSize / 2));
601                 //如果当前字符X坐标小于字体的二分之一大小     
602                 if (point.X < textFontSize / 2)
603                 {
604                     point.X = point.X + textFontSize / 2;
605                 }
606                 //防止文字叠加         
607                 if (i > 0 && (point.X - sPoint.X < (textFontSize / 2 + textFontSize / 2)))
608                 {
609                     point.X = point.X + textFontSize;
610                 }
611                 //如果当前字符X坐标大于图片宽度,就减去字体的宽度        
612                 if (point.X > (bgWidth - textFontSize / 2))
613                 {
614                     point.X = bgWidth - textFontSize / 2;
615                 }
616                 sPoint = point;
617                 float angle = random.Next(-rotationAngle, rotationAngle);//转动的度数   
618                 g.TranslateTransform(point.X, point.Y);
619                 g.RotateTransform(angle);
620 
621                 Rectangle myretang = new Rectangle(0, 1, Convert.ToInt32(textFont.Size), Convert.ToInt32(textFont.Size));
622                 Color c = GetRandomDeepColor();
623                 //设置渐变画刷
624                 LinearGradientBrush mybrush2 = new LinearGradientBrush(myretang, c, GetLightColor(c, 120), random.Next(180));
625                 g.DrawString(chars[i].ToString(), textFont, mybrush2, 1, 1, format);
626 
627                 g.RotateTransform(-angle);//转回去
628                 g.TranslateTransform(-point.X, -point.Y);//移动光标到指定位置,每个字符紧凑显示,避免被软件识别
629                 strPoint[i] = point;
630                 textFont.Dispose();
631                 mybrush2.Dispose();
632             }
633             return b;
634         }
635         #endregion
636 
637         #region 增加或減少亮度
638         /// <summary>            
639         /// 增加或減少亮度            
640         /// </summary>            
641         /// <param name="img">System.Drawing.Image Source </param>           
642         /// <param name="valBrightness">0~255</param>            
643         /// <returns></returns>       
644         public System.Drawing.Bitmap AdjustBrightness(System.Drawing.Image img, int valBrightness)
645         {
646             // 讀入欲轉換的圖片並轉成為 Bitmap             
647             System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(img);
648             for (int y = 0; y < bitmap.Height; y++)
649             {
650                 for (int x = 0; x < bitmap.Width; x++)
651                 {
652                     // 取得每一個 pixel         
653                     var pixel = bitmap.GetPixel(x, y);
654                     // 判斷 如果處理過後 255 就設定為 255 如果小於則設定為 0         
655                     var pR = ((pixel.R + valBrightness > 255) ? 255 : pixel.R + valBrightness) < 0 ? 0 : ((pixel.R + valBrightness > 255) ? 255 : pixel.R + valBrightness);
656                     var pG = ((pixel.G + valBrightness > 255) ? 255 : pixel.G + valBrightness) < 0 ? 0 : ((pixel.G + valBrightness > 255) ? 255 : pixel.G + valBrightness);
657                     var pB = ((pixel.B + valBrightness > 255) ? 255 : pixel.B + valBrightness) < 0 ? 0 : ((pixel.B + valBrightness > 255) ? 255 : pixel.B + valBrightness);
658                     // 將改過的 RGB 寫回         
659                     System.Drawing.Color newColor = System.Drawing.Color.FromArgb(pixel.A, pR, pG, pB);
660                     bitmap.SetPixel(x, y, newColor);
661                 }
662             }
663             // 回傳結果      
664             return bitmap;
665         }
666         #endregion
667 
668         #region 水波纹效果    
669         /// <summary>           
670         /// 水波纹效果            
671         /// </summary>            
672         /// <param name="src"></param>            
673         /// <param name="nWave">坡度</param>            
674         /// www.it165.net            
675         /// <returns></returns>            
676         public Bitmap AdjustRippleEffect(Bitmap src, short nWave)
677         {
678             int nWidth = src.Width;
679             int nHeight = src.Height;
680             // 透过公式进行水波纹的採样             
681             PointF[,] fp = new PointF[nWidth, nHeight];
682             Point[,] pt = new Point[nWidth, nHeight];
683             Point mid = new Point();
684             mid.X = nWidth / 2;
685             mid.Y = nHeight / 2;
686             double newX, newY;
687             double xo, yo;
688             //先取样将水波纹座标跟RGB取出  
689             for (int x = 0; x < nWidth; ++x)
690                 for (int y = 0; y < nHeight; ++y)
691                 {
692                     xo = ((double)nWave * Math.Sin(2.0 * 3.1415 * (float)y / 128.0));
693                     yo = ((double)nWave * Math.Cos(2.0 * 3.1415 * (float)x / 128.0));
694                     newX = (x + xo);
695                     newY = (y + yo);
696                     if (newX > 0 && newX < nWidth)
697                     {
698                         fp[x, y].X = (float)newX;
699                         pt[x, y].X = (int)newX;
700                     }
701                     else
702                     {
703                         fp[x, y].X = (float)0.0;
704                         pt[x, y].X = 0;
705                     }
706                     if (newY > 0 && newY < nHeight)
707                     {
708                         fp[x, y].Y = (float)newY;
709                         pt[x, y].Y = (int)newY;
710                     }
711                     else
712                     {
713                         fp[x, y].Y = (float)0.0;
714                         pt[x, y].Y = 0;
715                     }
716                 }
717             //进行合成              
718             Bitmap bSrc = (Bitmap)src.Clone();
719             // 依照 Format24bppRgb 每三个表示一 Pixel 0: 蓝 1: 绿 2: 红   
720             BitmapData bitmapData = src.LockBits(new Rectangle(0, 0, src.Width, src.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
721             BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
722             int scanline = bitmapData.Stride;
723             IntPtr Scan0 = bitmapData.Scan0;
724             IntPtr SrcScan0 = bmSrc.Scan0;
725             //指针在c#中是不提倡使用的,有关指针的操作被认为是不安全的(unsafe)。因此运行这段代码之前,先要改一个地方,否则编译不过无法运行。
726             //修改方法:找到你的项目,在项目图标上点右键,选项目属性(Properties),Build标签页里把Allow unsafe code勾选上
727             unsafe
728             {
729                 //指针
730                 byte* p = (byte*)(void*)Scan0;
731                 byte* pSrc = (byte*)(void*)SrcScan0;
732                 int nOffset = bitmapData.Stride - src.Width * 3;
733                 int xOffset, yOffset;
734                 for (int y = 0; y < nHeight; ++y)
735                 {
736                     for (int x = 0; x < nWidth; ++x)
737                     {
738                         xOffset = pt[x, y].X;
739                         yOffset = pt[x, y].Y;
740                         if (yOffset >= 0 && yOffset < nHeight && xOffset >= 0 && xOffset < nWidth)
741                         {
742                             p[0] = pSrc[(yOffset * scanline) + (xOffset * 3)];
743                             p[1] = pSrc[(yOffset * scanline) + (xOffset * 3) + 1];
744                             p[2] = pSrc[(yOffset * scanline) + (xOffset * 3) + 2];
745                         }
746                         p += 3;
747                     }
748                     p += nOffset;
749                 }
750             }
751             src.UnlockBits(bitmapData);
752             bSrc.UnlockBits(bmSrc);
753             return src;
754         }
755         #endregion
756 
757         #region 生成随机字符串
758         /// <summary>            
759         /// 生成随机字符串                
760         /// </summary>            
761         /// <returns></returns>            
762         public string GetRandomString(Int32 textLength)
763         {
764             string[] randomArray = charCollection.Split(','); //将字符串生成数组        
765             int arrayLength = randomArray.Length;
766             string randomString = "";
767             for (int i = 0; i < textLength; i++)
768             {
769                 randomString += randomArray[random.Next(0, arrayLength)];
770             }
771             return randomString; //长度是textLength +1          
772         }
773         #endregion
774 
775         #region 随机生成颜色值    
776         /// <summary>      
777         /// 生成随机深颜色            
778         /// </summary>            
779         /// <returns></returns>  
780         public Color GetRandomDeepColor()
781         {
782             int nRed, nGreen, nBlue;
783             // nBlue,nRed  nGreen 相差大一点 nGreen 小一些    
784             //int high = 255;                     
785             int redLow = 160;
786             int greenLow = 100;
787             int blueLow = 160;
788             nRed = random.Next(redLow);
789             nGreen = random.Next(greenLow);
790             nBlue = random.Next(blueLow);
791             Color color = Color.FromArgb(nRed, nGreen, nBlue);
792             return color;
793         }
794         /// <summary>            
795         /// 生成随机浅颜色            
796         /// </summary>            
797         /// <returns>randomColor</returns>     
798         public Color GetRandomLightColor()
799         {
800             int nRed, nGreen, nBlue;
801             //越大颜色越浅       
802             int low = 180;            //色彩的下限              
803             int high = 255;            //色彩的上限          
804             nRed = random.Next(high) % (high - low) + low;
805             nGreen = random.Next(high) % (high - low) + low;
806             nBlue = random.Next(high) % (high - low) + low;
807             Color color = Color.FromArgb(nRed, nGreen, nBlue);
808             return color;
809         }
810         /// <summary>            
811         /// 获取与当前颜色值相加后的颜色            
812         /// </summary>            
813         /// <param name="c"></param>            
814         /// <returns></returns>           
815         public Color GetLightColor(Color c, Int32 value)
816         {
817             int nRed = c.R, nGreen = c.G, nBlue = c.B;
818             //越大颜色越浅               
819             if (nRed + value < 255 && nRed + value > 0)
820             {
821                 nRed = c.R + 40;
822             }
823             if (nGreen + value < 255 && nGreen + value > 0)
824             {
825                 nGreen = c.G + 40;
826             }
827             if (nBlue + value < 255 && nBlue + value > 0)
828             {
829                 nBlue = c.B + 40;
830             }
831             Color color = Color.FromArgb(nRed, nGreen, nBlue);
832             return color;
833         }
834         #endregion
835 
836         #region 绘制圆角矩形      
837         /// <summary>            
838         /// C# GDI+ 绘制圆角矩形            
839         /// </summary>            
840         /// <param name="g">Graphics 对象</param>           
841         /// <param name="rectangle">Rectangle 对象,圆角矩形区域</param>           
842         /// <param name="borderColor">边框颜色</param>            
843         /// <param name="borderWidth">边框宽度</param>            
844         /// <param name="r">圆角半径</param>           
845         private static void DrawRoundRectangle(Graphics g, Rectangle rectangle, Color borderColor, float borderWidth, int r)
846         {
847             // 如要使边缘平滑,请取消下行的注释      
848             g.SmoothingMode = SmoothingMode.HighQuality;  
849             Pen p = new Pen(borderColor, borderWidth);
850             // 调用 getRoundRectangle 得到圆角矩形的路径,然后再进行绘制     
851             g.DrawPath(p, getRoundRectangle(rectangle, r));
852         }
853         #endregion
854 
855         #region 根据普通矩形得到圆角矩形的路径      
856         /// <summary>            
857         /// 根据普通矩形得到圆角矩形的路径            
858         /// </summary>           
859         /// <param name="rectangle">原始矩形</param>
860         /// <param name="r">半径</param>     
861         /// <returns>图形路径</returns> 
862         private static GraphicsPath getRoundRectangle(Rectangle rectangle, int r)
863         {
864             int l = 2 * r;
865             // 把圆角矩形分成八段直线、弧的组合,依次加到路径中           
866             GraphicsPath gp = new GraphicsPath();
867             gp.AddLine(new Point(rectangle.X + r, rectangle.Y), new Point(rectangle.Right - r, rectangle.Y));
868             gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Y, l, l), 270F, 90F);
869             gp.AddLine(new Point(rectangle.Right, rectangle.Y + r), new Point(rectangle.Right, rectangle.Bottom - r));
870             gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Bottom - l, l, l), 0F, 90F);
871             gp.AddLine(new Point(rectangle.Right - r, rectangle.Bottom), new Point(rectangle.X + r, rectangle.Bottom));
872             gp.AddArc(new Rectangle(rectangle.X, rectangle.Bottom - l, l, l), 90F, 90F);
873             gp.AddLine(new Point(rectangle.X, rectangle.Bottom - r), new Point(rectangle.X, rectangle.Y + r));
874             gp.AddArc(new Rectangle(rectangle.X, rectangle.Y, l, l), 180F, 90F);
875             return gp;
876         }
877         #endregion
878     }
View Code

调用

1         private void frmValidateCode_Load(object sender, EventArgs e)
2         {
3             ValidateCode vCode = new ValidateCode();
4             string code = vCode.GetRandomString(5);
5             MemoryStream stream = vCode.CreateImage(code);
6             pictureBox1.Image = new Bitmap(stream);
7         }

效果

原文地址:https://www.cnblogs.com/WarBlog/p/11189717.html