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


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

    一、验证码

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

    调用

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

    效果

  • 相关阅读:
    Django登录逻辑,中间用到Cookie创建、读取、删除、等操作
    CBV和FBV用户认证装饰器
    Django Session配置
    Django基于Cookie装饰器实现用户认证
    回归博客
    Jenkins部署
    iostat命令详解
    被入侵和删除木马程序的经历
    centos7 centos-home 磁盘转移至centos-root下
    zabbix图形显示口口不显示汉字
  • 原文地址:https://www.cnblogs.com/WarBlog/p/11189717.html
Copyright © 2020-2023  润新知