关于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

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

  1. 戏说 .NET GDI+系列学习教程(三、Graphics类的方法的总结)

    转载于:https://www.cnblogs.com/WarBlog/p/11157395.html

  2. 戏说 .NET GDI+系列学习教程(二、Graphics类的方法)

    一.DrawBezier 画立体的贝尔塞曲线 private void frmGraphics_Paint(object sender, PaintEventArgs e){Graphics g = ...

  3. GDI+ Graphics类

    1 GDI+的核心:Graphics类 (1)The Graphics class provides methods for drawing lines, curves, figures, image ...

  4. Win32中GDI+应用(三)---Graphics类

    在我理解看来,Graphics是一个device context和你的drawing conetent之间的一个中介.它存储了device context的相关属性,以及drawing content ...

  5. java中math.ceil用法_[Java教程]关于Math类的round、floor、ceil三个方法

    [Java教程]关于Math类的round.floor.ceil三个方法 0 2014-05-06 16:00:08 一.Math类这三个方法的简介 1.round():取最接近的值. 对于这个方法, ...

  6. GDI+——使用Graphics类绘制基本图形

    目录 绘制基本图形 绘制直线 绘制矩形 绘制椭圆 绘制圆弧 绘制扇形 绘制多边形 绘制文本 综合案例 绘制波形曲线 使用双缓冲技术绘图 绘制基本图形 绘制直线 绘制直线用到了Graphics类的Dra ...

  7. 【转】c#数字图像处理(一)Bitmap类、 Bitmapdata类和 Graphics类

    转自:https://www.cnblogs.com/dearzhoubi/p/8553763.html Bitmap类. Bitmapdata类和 Graphics类是C#图像处理中最重要的3个类, ...

  8. java绘图之Graphics类

    1.画图实现原理 Component类中提供了三个与绘图有关的三个方法. paint(Graphics g):绘制组件的外观. update(Graphics g):调用paint方法,刷新组件外观 ...

  9. Quartz教程三:Job与JobDetail介绍

    Quartz教程三:Job与JobDetail介绍 原文链接 | 译文链接 | 翻译:nkcoder | 校对: 本系列教程由quartz-2.2.x官方文档翻译.整理而来,希望给同样对quartz感 ...

最新文章

  1. 2月15日Python线上峰会免费学!6场精华分享,用代码“抗”疫
  2. 深入Android 【一】 —— 序及开篇
  3. usestate中的回调函数_React 中获取数据的 3 种方法:哪种最好?
  4. 深度学习——卷积神经网络 的经典网络(LeNet-5、AlexNet、ZFNet、VGG-16、GoogLeNet、ResNet)
  5. 山西职称计算机考试报名时间 2014,2014山西省6月份职称计算机考试报名入口
  6. python 绘图与可视化 Graphviz 二叉树 、 error: Microsoft Visual C++ 14.0 is required
  7. 【clickhouse】clickhouse 临时表
  8. 第二次冲刺-个人工作总结05
  9. 嵌入式系统Linux内核开发学习指导框图
  10. 仿任务面板 跨多个RecyclerView的Item拖动 支持缩小后拖动
  11. Riverbed实现云内外的端到端可视化
  12. android多击事件_android自定义OnTouchEvent处理长按,单击,双击,多击事件和Touch
  13. AWS DeepRacer ROS 架构 模拟环境和真实赛道的区别
  14. 自制狂拍灰太狼小游戏(HTML+CSS+JavaScript)
  15. Invalid bound statement (not found): com.example.wyl.mapper.PeijianDAO.selectList异常错误
  16. python批量下载bilibili视频_python批量提取哔哩哔哩bilibili视频
  17. 瑞幸咖啡,不过是又一个“逃离美团者”
  18. 华为云IoT设备接入服务全体验
  19. 魔兽争霸英雄属性全揭秘
  20. linux中萌翻了的cowsay命令

热门文章

  1. Linked List Cycle II
  2. c语言函数库学习~sscanf~格式化输入
  3. 操作系统--内存管理方式
  4. pyQt 每日一练习 -- 登录框
  5. 链接全局变量再说BSS段的清理
  6. IEs 4 Linux 新版支撑 IE 7
  7. (转)TabContainer要实现服务器端回传
  8. shell监控java接口服务_Linux系统下Java通过shell脚本监控重启服务
  9. windows nodejs mysql_windows server 安装 mysql + nondejs连接mysql
  10. 《OpenCV3编程入门》学习笔记7 图像变换(二 )霍夫变换