日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

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

發(fā)布時間:2023/11/27 生活经验 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 戏说 .NET GDI+系列学习教程(三、Graphics类的应用_验证码) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

關(guān)于Graphics也有了基本了解下面想說的的是學(xué)這個東東干什么呢,到底如何應(yīng)用
目前常見應(yīng)用
1、驗證碼(參照網(wǎng)上的)
2、打印排版(會提到關(guān)于條形碼大小設(shè)置)
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         /// 獲取隨機(jī)驗證碼
 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         /// 獲取和設(shè)置驗證碼字符串的長度
 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         //驗證碼的寬度,默認(rèn)為130
 39         private int bgWidth = 130;
 40 
 41         /// <summary>
 42         /// 驗證碼的寬度,默認(rèn)為130
 43         /// </summary>
 44         public Int32 Width
 45         {
 46             get { return bgWidth; }
 47             set { bgWidth = value; }
 48         }
 49 
 50         //驗證碼的寬度,默認(rèn)為130
 51         private int bgHeight = 40;
 52 
 53         /// <summary>
 54         /// 驗證碼的高度,默認(rèn)為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         /// 驗證碼字體的最小值,默認(rèn)為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         /// 驗證碼字體的最大值,默認(rèn)為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         /// 驗證碼字體的顏色,默認(rèn)為系統(tǒng)自動生成字體顏色
 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         /// 驗證碼的背景色,默認(rèn)為Color.FromArgb(243, 251, 254)
101         /// </summary>
102         public Color BackgroundColor
103         {
104             get { return backColor; }
105             set { backColor = value; }
106         }
107 
108         //貝塞爾曲線的條數(shù),默認(rèn)為3條
109         private Int32 bezierCount = 3;
110 
111         /// <summary>
112         /// 貝塞爾曲線的條數(shù),默認(rèn)為3條
113         /// </summary>
114         public Int32 BezierCount
115         {
116             get { return bezierCount; }
117             set { bezierCount = value; }
118         }
119 
120         //直線條數(shù),默認(rèn)為3條
121         private Int32 lineCount = 3;
122 
123         /// <summary>
124         /// 直線條數(shù),默認(rèn)為3條
125         /// </summary>
126         public Int32 LineCount
127         {
128             get { return lineCount; }
129             set { lineCount = value; }
130         }
131 
132         //隨機(jī)字符串列表
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"; //定義驗證碼字符及出現(xiàn)頻次 ,避免出現(xiàn)0 o j i l 1 x; 
134 
135         /// <summary>
136         /// 隨機(jī)字符串列表,請使用英文狀態(tài)下的逗號分隔
137         /// </summary>
138         public String CharCollection
139         {
140             get { return charCollection; }
141             set { charCollection = value; }
142         }
143 
144         //驗證碼字符串個數(shù),默認(rèn)為4個字符
145         private Int32 intCount = 4;
146 
147         /// <summary>
148         /// 驗證碼字符串個數(shù),默認(rèn)為4個字符
149         /// </summary>
150         public Int32 IntCount
151         {
152             get { return intCount; }
153             set { intCount = value; }
154         }
155 
156         //是否添加噪點(diǎn),默認(rèn)添加,噪點(diǎn)顏色為系統(tǒng)隨機(jī)生成。
157         private Boolean isPixel = true;
158         /// <summary>
159         /// 是否添加噪點(diǎn),默認(rèn)添加,噪點(diǎn)顏色為系統(tǒng)隨機(jī)生成。
160         /// </summary>
161         public Boolean IsPixel
162         {
163             get { return isPixel; }
164             set { isPixel = value; }
165         }
166 
167         //是否添加隨機(jī)噪點(diǎn)字符串,默認(rèn)添加
168         private Boolean isRandString = true;
169         /// <summary>
170         /// 是否添加隨機(jī)噪點(diǎn)字符串,默認(rèn)添加
171         /// </summary>
172         public Boolean IsRandString
173         {
174             get { return isRandString; }
175             set { isRandString = value; }
176         }
177 
178         /// <summary>
179         /// 隨機(jī)背景字符串的個數(shù)
180         /// </summary>
181         public Int32 RandomStringCount
182         {
183             get; set;
184         }
185 
186         //隨機(jī)背景字符串的大小
187         private Int32 randomStringFontSize = 9;
188         /// <summary>
189         /// 隨機(jī)背景字符串的大小
190         /// </summary>
191         public Int32 RandomStringFontSize
192         {
193             get { return randomStringFontSize; }
194             set { randomStringFontSize = value; }
195         }
196 
197         /// <summary>
198         /// 是否對圖片進(jìn)行扭曲
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         /// 驗證碼字符串隨機(jī)轉(zhuǎn)動的角度 默認(rèn)40
226         /// </summary>
227         private Int32 rotationAngle = 40;
228         /// <summary>
229         /// 驗證碼字符串隨機(jī)轉(zhuǎn)動的角度的最大值
230         /// </summary>
231         public Int32 RotationAngle
232         {
233             get { return rotationAngle; }
234             set { rotationAngle = value; }
235         }
236 
237         /// <summary>
238         /// 設(shè)置或獲取邊框樣式
239         /// </summary>
240         public BorderStyle Border
241         {
242             get; set;
243         }
244 
245         /// <summary>
246         /// 對驗證碼圖片進(jìn)行高斯模糊的閥值,如果設(shè)置為0
247         /// </summary>
248         private Double gaussianDeviation = 0;
249 
250         /// <summary>
251         /// 對驗證碼圖片進(jìn)行高斯模糊的閥值,如果設(shè)置為0,則不對圖片進(jìn)行高斯模糊,該設(shè)置可能會對圖片處理的性能有較大影響
252         /// </summary>
253         public Double GaussianDeviation
254         {
255             get { return gaussianDeviation; }
256             set { gaussianDeviation = value; }
257         }
258         private Int32 brightnessValue = 0;
259         /// <summary>
260         /// 對圖片進(jìn)行暗度和亮度的調(diào)整,如果該值為0,則不調(diào)整。該設(shè)置會對圖片處理性能有較大影響
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         /// 構(gòu)造函數(shù),用于初始化常用變量
277         /// </summary>
278         public void DrawValidationCode()
279         {
280             //隨機(jī)對象 
281             //Random類所取到的系統(tǒng)時鐘種子接近甚至完全一樣
282             //解決方案:new Random(Guid.NewGuid().GetHashCode());
283             random = new Random(Guid.NewGuid().GetHashCode());
284             //坐標(biāo)數(shù)組
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.噪點(diǎn)
297         /// 1.1.3.干擾文字
298         /// 1.1.4.干擾線條(直線、曲線)
299         /// 2.驗證碼字符
300         /// 3.驗證碼圖片扭曲
301         /// 4.驗證碼圖片模糊
302         /// 5.驗證碼圖片亮度
303         /// 6.驗證碼圖片保持在內(nèi)存流中
304         /// </summary>
305         /// <param name="target">用于存儲圖片的一般字節(jié)序列</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(畫板)根據(jù)圖片對象 
312             dc = Graphics.FromImage(bit);
313             /*
314                 SmoothingModeAntiAlias      指定消除鋸齒的呈現(xiàn)。
315                 SmoothingModeDefault        指定默認(rèn)模式。
316                 SmoothingModeHighQuality    指定高質(zhì)量、低速度呈現(xiàn)。
317                 SmoothingModeHighSpeed      指定高速度、低質(zhì)量呈現(xiàn)。
318                 SmoothingModeInvalid        指定一個無效模式。
319                 SmoothingModeNone           指定不消除鋸齒。
320             */
321             dc.SmoothingMode = SmoothingMode.HighQuality;
322             //文本的呈現(xiàn)模式
323             dc.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
324             // 插補(bǔ)模式
325             dc.InterpolationMode = InterpolationMode.HighQualityBilinear;
326             //合成圖像的呈現(xiàn)質(zhì)量
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                 //對圖片文字進(jìn)行扭曲
339                 bit = AdjustRippleEffect(bit, 5);
340                 //對圖片進(jìn)行高斯模糊
341                 if (gaussianDeviation > 0)
342                 {
343                     Gaussian gau = new Gaussian();
344                     bit = gau.FilterProcessImage(gaussianDeviation, bit);
345                 }
346                 //進(jìn)行暗度和亮度處理
347                 if (brightnessValue != 0)
348                 {
349                     //對圖片進(jìn)行調(diào)暗處理 
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 畫驗證碼背景,例如,增加早點(diǎn),添加曲線和直線等            
366         /// <summary>
367         /// 畫驗證碼背景,例如,增加早點(diǎn),添加曲線和直線等
368         /// 1.1.背景包含
369         /// 1.1.1.背景顏色
370         /// 1.1.2.噪點(diǎn)
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             //畫噪點(diǎn)           
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 畫隨機(jī)噪點(diǎn)
411         /// <summary>            
412         /// 畫隨機(jī)噪點(diǎn)
413         /// 在指定區(qū)域中隨機(jī)設(shè)置像素點(diǎn)的顏色
414         /// </summary>            
415         /// <param name="pixNum">噪點(diǎn)的百分比</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             //畫噪點(diǎn)                
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                 //設(shè)置隨機(jī)像素點(diǎn)的顏色
431                 b.SetPixel(x, y, GetRandomDeepColor());
432                 //下移坐標(biāo)重新畫點(diǎn)                    
433                 if ((x + 1) < b.Width && (y + 1) < b.Height)
434                 {
435                     //畫圖片的前景噪音點(diǎn)   
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             //設(shè)置透明
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             //設(shè)置字體顯示格式         
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; //隨機(jī)轉(zhuǎn)動角度
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                 //隨機(jī)轉(zhuǎn)動的度數(shù)                
472                 float angle = random.Next(-randAngle, randAngle);
473                 //轉(zhuǎn)動畫布                 
474                 g.RotateTransform(angle);
475                 g.DrawString(randStr[random.Next(randStr.Length)], textFont, brush, pot, format);
476                 //轉(zhuǎn)回去,為下一個字符做準(zhǔn)備
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 隨機(jī)生成貝塞爾曲線           
489         /// <summary>            
490         /// 隨機(jī)生成貝塞爾曲線            
491         /// </summary>            
492         /// <param name="bmp">一個圖片的實例</param>            
493         /// <param name="lineNum">線條數(shù)量</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">線條個數(shù)</param>            
541         /// <returns></returns>           
542         public Bitmap DrawRandomLine(Int32 lineNum)
543         {
544             if (lineNum < 0) throw new ArgumentNullException("參數(shù)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("字體最大值參數(shù)FontMaxSize與驗證碼高度相近,這會導(dǎo)致描繪驗證碼字符串時出錯,請重新設(shè)置參數(shù)!");
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();            //拆散字符串成單字符數(shù)組     
580             validationCode = chars.ToString();
581             //設(shè)置字體顯示格式            
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                 // 字符位置坐標(biāo)
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                 //如果當(dāng)前字符X坐標(biāo)小于字體的二分之一大小     
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                 //如果當(dāng)前字符X坐標(biāo)大于圖片寬度,就減去字體的寬度        
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);//轉(zhuǎn)動的度數(shù)   
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                 //設(shè)置漸變畫刷
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);//轉(zhuǎn)回去
628                 g.TranslateTransform(-point.X, -point.Y);//移動光標(biāo)到指定位置,每個字符緊湊顯示,避免被軟件識別
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             // 讀入欲轉(zhuǎn)換的圖片並轉(zhuǎn)成為 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 就設(shè)定為 255 如果小於則設(shè)定為 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             // 回傳結(jié)果      
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             // 透過公式進(jìn)行水波紋的採樣             
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             //先取樣將水波紋座標(biāo)跟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             //進(jìn)行合成              
718             Bitmap bSrc = (Bitmap)src.Clone();
719             // 依照 Format24bppRgb 每三個表示一 Pixel 0: 藍(lán) 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#中是不提倡使用的,有關(guān)指針的操作被認(rèn)為是不安全的(unsafe)。因此運(yùn)行這段代碼之前,先要改一個地方,否則編譯不過無法運(yùn)行。
726             //修改方法:找到你的項目,在項目圖標(biāo)上點(diǎn)右鍵,選項目屬性(Properties),Build標(biāo)簽頁里把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 生成隨機(jī)字符串
758         /// <summary>            
759         /// 生成隨機(jī)字符串                
760         /// </summary>            
761         /// <returns></returns>            
762         public string GetRandomString(Int32 textLength)
763         {
764             string[] randomArray = charCollection.Split(','); //將字符串生成數(shù)組        
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 隨機(jī)生成顏色值    
776         /// <summary>      
777         /// 生成隨機(jī)深顏色            
778         /// </summary>            
779         /// <returns></returns>  
780         public Color GetRandomDeepColor()
781         {
782             int nRed, nGreen, nBlue;
783             // nBlue,nRed  nGreen 相差大一點(diǎn) 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         /// 生成隨機(jī)淺顏色            
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         /// 獲取與當(dāng)前顏色值相加后的顏色            
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 對象,圓角矩形區(qū)域</param>           
842         /// <param name="borderColor">邊框顏色</param>            
843         /// <param name="borderWidth">邊框?qū)挾?/span></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             // 調(diào)用 getRoundRectangle 得到圓角矩形的路徑,然后再進(jìn)行繪制     
851             g.DrawPath(p, getRoundRectangle(rectangle, r));
852         }
853         #endregion
854 
855         #region 根據(jù)普通矩形得到圓角矩形的路徑      
856         /// <summary>            
857         /// 根據(jù)普通矩形得到圓角矩形的路徑            
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

調(diào)用

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         }

效果

?

轉(zhuǎn)載于:https://www.cnblogs.com/WarBlog/p/11189717.html

總結(jié)

以上是生活随笔為你收集整理的戏说 .NET GDI+系列学习教程(三、Graphics类的应用_验证码)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。