博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
戏说 .NET GDI+系列学习教程(三、Graphics类的应用_验证码)
阅读量:5285 次
发布时间:2019-06-14

本文共 33857 字,大约阅读时间需要 112 分钟。

关于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         ///  12         /// 获取随机验证码 13         ///  14         public String ValidationCode 15         { 16             get { return validationCode; } 17         } 18  19         ///  20         /// 验证码字符串的长度 21         ///  22         private Int32 validationCodeCount = 4; 23  24         ///  25         /// 获取和设置验证码字符串的长度 26         ///  27         public Int32 ValidationCodeCount 28         { 29             get { return validationCodeCount; } 30             set { validationCodeCount = value; } 31         } 32  33         ///  34         /// 画板对象 35         ///  36         Graphics dc = null; 37  38         //验证码的宽度,默认为130 39         private int bgWidth = 130; 40  41         ///  42         /// 验证码的宽度,默认为130 43         ///  44         public Int32 Width 45         { 46             get { return bgWidth; } 47             set { bgWidth = value; } 48         } 49  50         //验证码的宽度,默认为130 51         private int bgHeight = 40; 52  53         ///  54         /// 验证码的高度,默认为40 55         ///  56         public Int32 Height 57         { 58             get { return bgHeight; } 59             set { bgHeight = value; } 60         } 61  62         //字体大小 字体最小值 63         private int fontMinSize = 20; 64  65         ///  66         /// 验证码字体的最小值,默认为20,建议不小于15像素 67         ///  68         public Int32 FontMinSize 69         { 70             get { return fontMinSize; } 71             set { fontMinSize = value; } 72         } 73         //字体大小 字体最大值 74         private Int32 fontMaxSize = 25; 75  76         ///  77         /// 验证码字体的最大值,默认为25 78         ///  79         public Int32 FontMaxSize 80         { 81             get { return fontMaxSize; } 82             set { fontMaxSize = value; } 83         } 84  85         //验证码字体的颜色 86         private Color[] fontColor = { }; 87  88         ///  89         /// 验证码字体的颜色,默认为系统自动生成字体颜色 90         ///  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         /// 100         /// 验证码的背景色,默认为Color.FromArgb(243, 251, 254)101         /// 102         public Color BackgroundColor103         {104             get { return backColor; }105             set { backColor = value; }106         }107 108         //贝塞尔曲线的条数,默认为3条109         private Int32 bezierCount = 3;110 111         /// 112         /// 贝塞尔曲线的条数,默认为3条113         /// 114         public Int32 BezierCount115         {116             get { return bezierCount; }117             set { bezierCount = value; }118         }119 120         //直线条数,默认为3条121         private Int32 lineCount = 3;122 123         /// 124         /// 直线条数,默认为3条125         /// 126         public Int32 LineCount127         {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         /// 136         /// 随机字符串列表,请使用英文状态下的逗号分隔137         /// 138         public String CharCollection139         {140             get { return charCollection; }141             set { charCollection = value; }142         }143 144         //验证码字符串个数,默认为4个字符145         private Int32 intCount = 4;146 147         /// 148         /// 验证码字符串个数,默认为4个字符149         /// 150         public Int32 IntCount151         {152             get { return intCount; }153             set { intCount = value; }154         }155 156         //是否添加噪点,默认添加,噪点颜色为系统随机生成。157         private Boolean isPixel = true;158         /// 159         /// 是否添加噪点,默认添加,噪点颜色为系统随机生成。160         /// 161         public Boolean IsPixel162         {163             get { return isPixel; }164             set { isPixel = value; }165         }166 167         //是否添加随机噪点字符串,默认添加168         private Boolean isRandString = true;169         /// 170         /// 是否添加随机噪点字符串,默认添加171         /// 172         public Boolean IsRandString173         {174             get { return isRandString; }175             set { isRandString = value; }176         }177 178         /// 179         /// 随机背景字符串的个数180         /// 181         public Int32 RandomStringCount182         {183             get; set;184         }185 186         //随机背景字符串的大小187         private Int32 randomStringFontSize = 9;188         /// 189         /// 随机背景字符串的大小190         /// 191         public Int32 RandomStringFontSize192         {193             get { return randomStringFontSize; }194             set { randomStringFontSize = value; }195         }196 197         /// 198         /// 是否对图片进行扭曲199         /// 200         public Boolean IsTwist201         {202             get; set;203         }204 205         /// 206         /// 边框样式207         /// 208         public enum BorderStyle209         {210             /// 211             /// 无边框212             /// 213             None,214             /// 215             /// 矩形边框216             /// 217             Rectangle,218             /// 219             /// 圆角边框220             /// 221             RoundRectangle222         }223 224         /// 225         /// 验证码字符串随机转动的角度 默认40226         /// 227         private Int32 rotationAngle = 40;228         /// 229         /// 验证码字符串随机转动的角度的最大值230         /// 231         public Int32 RotationAngle232         {233             get { return rotationAngle; }234             set { rotationAngle = value; }235         }236 237         /// 238         /// 设置或获取边框样式239         /// 240         public BorderStyle Border241         {242             get; set;243         }244 245         /// 246         /// 对验证码图片进行高斯模糊的阀值,如果设置为0247         /// 248         private Double gaussianDeviation = 0;249 250         /// 251         /// 对验证码图片进行高斯模糊的阀值,如果设置为0,则不对图片进行高斯模糊,该设置可能会对图片处理的性能有较大影响252         /// 253         public Double GaussianDeviation254         {255             get { return gaussianDeviation; }256             set { gaussianDeviation = value; }257         }258         private Int32 brightnessValue = 0;259         /// 260         /// 对图片进行暗度和亮度的调整,如果该值为0,则不调整。该设置会对图片处理性能有较大影响261         /// 262         public Int32 BrightnessValue263         {264             get { return brightnessValue; }265             set { brightnessValue = value; }266         }267 268         #endregion269 270 271         private Point[] strPoint = null;272 273         Random random = new Random();274 275         /// 276         /// 构造函数,用于初始化常用变量277         /// 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         /// 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         /// 305         /// 用于存储图片的一般字节序列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             try329             {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             finally358             {359                 //brush.Dispose();        360                 bit.Dispose();361                 dc.Dispose();362             }363         }364 365         #region 画验证码背景,例如,增加早点,添加曲线和直线等            366         /// 367         /// 画验证码背景,例如,增加早点,添加曲线和直线等368         /// 1.1.背景包含369         /// 1.1.1.背景颜色370         /// 1.1.2.噪点371         /// 1.1.3.干扰文字372         /// 1.1.4.干扰线条(直线、曲线)373         /// 374         /// 
Bitmap 对象
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 #endregion409 410 #region 画随机噪点411 /// 412 /// 画随机噪点413 /// 在指定区域中随机设置像素点的颜色414 /// 415 /// 噪点的百分比 416 ///
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 #endregion442 443 #region 画干扰背景文字 444 /// 445 /// 画背景干扰文字 446 /// 447 ///
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 #endregion487 488 #region 随机生成贝塞尔曲线 489 /// 490 /// 随机生成贝塞尔曲线 491 /// 492 /// 一个图片的实例 493 /// 线条数量 494 ///
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 #endregion534 535 #region 画直线 536 /// 537 /// 画直线 538 /// 539 /// 一个bmp实例 540 /// 线条个数 541 ///
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 #endregion562 563 #region 写入验证码的字符串 564 /// 565 /// 写入验证码的字符串 566 /// 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 #endregion636 637 #region 增加或減少亮度638 /// 639 /// 增加或減少亮度 640 /// 641 /// System.Drawing.Image Source 642 /// 0~255 643 ///
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 #endregion667 668 #region 水波纹效果 669 /// 670 /// 水波纹效果 671 /// 672 /// 673 /// 坡度 674 /// www.it165.net 675 ///
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 else702 {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 else712 {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 unsafe728 {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 #endregion756 757 #region 生成随机字符串758 /// 759 /// 生成随机字符串 760 /// 761 ///
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 #endregion774 775 #region 随机生成颜色值 776 /// 777 /// 生成随机深颜色 778 /// 779 ///
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 /// 795 /// 生成随机浅颜色 796 /// 797 ///
randomColor
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 /// 811 /// 获取与当前颜色值相加后的颜色 812 /// 813 /// 814 ///
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 #endregion835 836 #region 绘制圆角矩形 837 /// 838 /// C# GDI+ 绘制圆角矩形 839 /// 840 /// Graphics 对象 841 /// Rectangle 对象,圆角矩形区域 842 /// 边框颜色 843 /// 边框宽度 844 /// 圆角半径 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 #endregion854 855 #region 根据普通矩形得到圆角矩形的路径 856 /// 857 /// 根据普通矩形得到圆角矩形的路径 858 /// 859 /// 原始矩形860 /// 半径 861 ///
图形路径
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 #endregion878 }
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

你可能感兴趣的文章
div或者p标签单行和多行超出显示省略号
查看>>
Elasticsearch 滚动重启 必读
查看>>
Hadoop基本概念
查看>>
java.util.zip压缩打包文件总结一:压缩文件及文件下面的文件夹
查看>>
浅说 apache setenvif_module模块
查看>>
MySQL--数据插入
查看>>
重新学习python系列(二)? WTF?
查看>>
shell脚本统计文件中单词的个数
查看>>
SPCE061A学习笔记
查看>>
sql 函数
查看>>
hdu 2807 The Shortest Path 矩阵
查看>>
熟悉项目需求,要知道产品增删修改了哪些内容,才会更快更准确的在该项目入手。...
查看>>
JavaScript 变量
查看>>
java实用类
查看>>
smarty模板自定义变量
查看>>
研究称90%的癌症由非健康生活习惯导致
查看>>
命令行启动Win7系统操作部分功能
查看>>
排序sort (一)
查看>>
Teamcenter10 step-by-step installation in Linux env-Oracle Server Patch
查看>>
Struts2学习(三)
查看>>