每个字符旋转随机角度的图象验证码 V2.0

根据 jeff377 的话,竹子将这验证码改进了一下,请大家讨论看看。
------- jeff377--------------------------------------------
我研究所的论文就是在做类神经网络处理文字辨识,以你的例子而言,旋转随意角度对辨识来说并不会有太大影响,只要抓字的重心,360度旋转抓取特微值,还是可以辨识的出来。
通常文字辨识的有一个重要的动作,就是要把个别文字分割,你只要把文字弄的难分割就有不错的安全性。
---------------------------------------------------

代码比较粗糙,而且比较菜,其中遇到一个问题, 未对 Graphics 填充底色,那么文字的 ClearType 效果没有了,文字毛边比较明显,不知道为什么,谁能告诉竹子?

代码相对粗糙,没有考虑更多的情况,在测试过程中,以20px 字体呈现,效果感觉还不错,只是 ClearType 效果没有了。

帖几张看看

------------

------------

------------

------------
有一些随机的不好,象下面这张


相关链接:
查看 V1.0

.NET 2.0 代码如下:
using  System;
using  System.Drawing;
using  System.Web;


namespace  Oran.Image
{
    
///   <summary>
    
///  旋转的可视验证码图象
    
///   </summary>
     public   class  RotatedVlidationCode
    {
        
public   enum  RandomStringMode
        {
            
///   <summary>
            
///  小写字母
            
///   </summary>
            LowerLetter,
            
///   <summary>
            
///  大写字母
            
///   </summary>
            UpperLetter,
            
///   <summary>
            
///  混合大小写字母
            
///   </summary>
            Letter,
            
///   <summary>
            
///  数字
            
///   </summary>
            Digital,
            
///   <summary>
            
///  混合数字与大小字母
            
///   </summary>
            Mix
        }

        
public   static   string  GenerateRandomString( int  length, RandomStringMode mode)
        {
            
string  rndStr  =   string .Empty;
            
if  (length  ==   0 )
                
return  rndStr;

            
// 以数组方式候选字符,可以更方便的剔除不要的字符,如数字 0 与字母 o
             char [] digitals  =   new   char [ 10 ] {  ' 0 ' ' 1 ' ' 2 ' ' 3 ' ' 4 ' ' 5 ' ' 6 ' ' 7 ' ' 8 ' ' 9 '  };
            
char [] lowerLetters  =   new   char [ 26 ] {
                
' 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 '  };
            
char [] upperLetters  =   new   char [ 26 ] {
                
' 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 '  };
            
char [] letters  =   new   char [ 52 ]{
                
' 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 '  };
            
char [] mix  =   new   char [ 62 ]{
                
' 0 ' ' 1 ' ' 2 ' ' 3 ' ' 4 ' ' 5 ' ' 6 ' ' 7 ' ' 8 ' ' 9 ' ,
                
' 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 '  };

            
int [] range  =   new   int [ 2 ] {  0 0  };
            Random random 
=   new  Random();

            
switch  (mode)
            {
                
case  RandomStringMode.Digital:
                    
for  ( int  i  =   0 ; i  <  length;  ++ i)
                        rndStr 
+=  digitals[random.Next( 0 , digitals.Length)];
                    
break ;

                
case  RandomStringMode.LowerLetter:
                    
for  ( int  i  =   0 ; i  <  length;  ++ i)
                        rndStr 
+=  lowerLetters[random.Next( 0 , lowerLetters.Length)];
                    
break ;

                
case  RandomStringMode.UpperLetter:
                    
for  ( int  i  =   0 ; i  <  length;  ++ i)
                        rndStr 
+=  upperLetters[random.Next( 0 , upperLetters.Length)];
                    
break ;

                
case  RandomStringMode.Letter:
                    
for  ( int  i  =   0 ; i  <  length;  ++ i)
                        rndStr 
+=  letters[random.Next( 0 , letters.Length)];
                    
break ;

                
default :
                    
for  ( int  i  =   0 ; i  <  length;  ++ i)
                        rndStr 
+=  mix[random.Next( 0 , mix.Length)];
                    
break ;
            }

            
return  rndStr;
        }

        
///   <summary>
        
///  显示验证码
        
///   </summary>
        
///   <param name="seed"> 随机数辅助种子 </param>
        
///   <param name="strLen"> 验证码字符长度 </param>
        
///   <param name="fontSize"> 字体大小 </param>
        
///   <param name="mode"> 随机字符模式 </param>
        
///   <param name="clrFont"> 字体颜色 </param>
        
///   <param name="clrBg"> 背景颜色 </param>
         public   static   void  ShowValidationCode( ref   int  seed,  int  strLen,  int  fontSize, RandomStringMode mode, Color clrFont, Color clrBg)
        {
            
int  tmpSeed;
            
unchecked
            {
                tmpSeed 
=  ( int )(seed  *  DateTime.Now.Ticks);
                
++ seed;
            }
            Random rnd 
=   new  Random(tmpSeed);

            
string  text  =  GenerateRandomString(strLen, mode);
            
int  height  =  fontSize  *   2 ;
            
//  因为字体旋转后每个字体所占宽度会所有加大,所以要加一点补偿宽度
             int  width  =  fontSize  *  text.Length  +  fontSize  /  (text.Length  -   2 );
            Bitmap bmp 
=   new  Bitmap(width, height);

            Graphics graphics 
=  Graphics.FromImage(bmp);
            Font font 
=   new  Font( " Courier New " , fontSize, FontStyle.Bold);
            Brush brush 
=   new  SolidBrush(clrFont);
            Brush brushBg 
=   new  SolidBrush(clrBg);
            graphics.FillRectangle(brushBg, 
0 0 , width, height);
            Bitmap tmpBmp 
=   new  Bitmap(height, height);
            Graphics tmpGph 
=   null ;
            
int  degree  =   40 ;
            Point tmpPoint 
=   new  Point();
            
for  ( int  i  =   0 ; i  <  text.Length; i ++ )
            {
                tmpBmp 
=   new  Bitmap(height, height);
                tmpGph 
=  Graphics.FromImage(tmpBmp);
               
//  tmpGph.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
               
//  不填充底色,文字 ClearType 效果不见了,why?!
               
//  tmpGph.FillRectangle(brushBg, 0, 0, tmpBmp.Width, tmpBmp.Height);
                degree  =  rnd.Next( 20 51 );  //  [20, 50]随机角度
                 if  (rnd.Next( 0 2 ==   0 )
                {
                    tmpPoint.X 
=   12 //  调整文本坐标以适应旋转后的图象
                    tmpPoint.Y  =   - 6 ;
                }
                
else
                {
                    degree 
=   ~ degree  +   1 //  逆时针旋转
                    tmpPoint.X  =   - 10 ;
                    tmpPoint.Y 
=   6 ;
                }

                tmpGph.RotateTransform(degree);
                tmpGph.DrawString(text[i].ToString(), font, brush, tmpPoint);
                graphics.DrawImage(tmpBmp, i 
*  fontSize,  0 );  //  拼接图象
            }
            
            
// 输出图象
            System.IO.MemoryStream memoryStream  =   new  System.IO.MemoryStream();
            bmp.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Gif);
            HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            HttpContext.Current.Response.ClearContent();
            HttpContext.Current.Response.ContentType 
=   " image/gif " ;
            HttpContext.Current.Response.BinaryWrite(memoryStream.ToArray());
            HttpContext.Current.Response.End();

            
// 释放资源
            font.Dispose();
            brush.Dispose();
            brushBg.Dispose();
            tmpGph.Dispose();
            tmpBmp.Dispose();
            graphics.Dispose();
            bmp.Dispose();
            memoryStream.Dispose();
        }
    }
}


转载于:https://www.cnblogs.com/iRed/archive/2008/06/22/1227687.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值