关于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 BackgroundColor 103 { 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 BezierCount 115 { 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 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 /// 136 /// 随机字符串列表,请使用英文状态下的逗号分隔 137 /// 138 public String CharCollection 139 { 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 IntCount 151 { 152 get { return intCount; } 153 set { intCount = value; } 154 } 155 156 //是否添加噪点,默认添加,噪点颜色为系统随机生成。 157 private Boolean isPixel = true; 158 /// 159 /// 是否添加噪点,默认添加,噪点颜色为系统随机生成。 160 /// 161 public Boolean IsPixel 162 { 163 get { return isPixel; } 164 set { isPixel = value; } 165 } 166 167 //是否添加随机噪点字符串,默认添加 168 private Boolean isRandString = true; 169 /// 170 /// 是否添加随机噪点字符串,默认添加 171 /// 172 public Boolean IsRandString 173 { 174 get { return isRandString; } 175 set { isRandString = value; } 176 } 177 178 /// 179 /// 随机背景字符串的个数 180 /// 181 public Int32 RandomStringCount 182 { 183 get; set; 184 } 185 186 //随机背景字符串的大小 187 private Int32 randomStringFontSize = 9; 188 /// 189 /// 随机背景字符串的大小 190 /// 191 public Int32 RandomStringFontSize 192 { 193 get { return randomStringFontSize; } 194 set { randomStringFontSize = value; } 195 } 196 197 /// 198 /// 是否对图片进行扭曲 199 /// 200 public Boolean IsTwist 201 { 202 get; set; 203 } 204 205 /// 206 /// 边框样式 207 /// 208 public enum BorderStyle 209 { 210 /// 211 /// 无边框 212 /// 213 None, 214 /// 215 /// 矩形边框 216 /// 217 Rectangle, 218 /// 219 /// 圆角边框 220 /// 221 RoundRectangle 222 } 223 224 /// 225 /// 验证码字符串随机转动的角度 默认40 226 /// 227 private Int32 rotationAngle = 40; 228 /// 229 /// 验证码字符串随机转动的角度的最大值 230 /// 231 public Int32 RotationAngle 232 { 233 get { return rotationAngle; } 234 set { rotationAngle = value; } 235 } 236 237 /// 238 /// 设置或获取边框样式 239 /// 240 public BorderStyle Border 241 { 242 get; set; 243 } 244 245 /// 246 /// 对验证码图片进行高斯模糊的阀值,如果设置为0 247 /// 248 private Double gaussianDeviation = 0; 249 250 /// 251 /// 对验证码图片进行高斯模糊的阀值,如果设置为0,则不对图片进行高斯模糊,该设置可能会对图片处理的性能有较大影响 252 /// 253 public Double GaussianDeviation 254 { 255 get { return gaussianDeviation; } 256 set { gaussianDeviation = value; } 257 } 258 private Int32 brightnessValue = 0; 259 /// 260 /// 对图片进行暗度和亮度的调整,如果该值为0,则不调整。该设置会对图片处理性能有较大影响 261 /// 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 /// 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 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 /// 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 #endregion 409 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 #endregion 442 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 #endregion 487 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 #endregion 534 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 #endregion 562 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 #endregion 636 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 #endregion 667 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 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 /// 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 #endregion 774 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 #endregion 835 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 #endregion 854 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 #endregion 878 }
调用
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 }
效果