扭曲的驗證碼


  當初學習一般處理程序的時候,寫過一個驗證碼,不過是后台程序向前台輸出了一張圖片,圖片上是幾個隨機寫上去的字符。雖然也驚訝於許多網站上那些“扭曲”的驗證碼,卻琢磨不透人家是怎么實現的,后來逐漸把這事遺忘了。今天在網上碰巧看到有人用php實現的案例,忍不住想着用C#來一把。當然,在此先感謝網上那位仁兄提供的思路,在下只是比着葫蘆畫瓢。

  這里所說的“扭曲”的驗證碼,只是字符扭曲。由於時間倉促,我也沒給顧得上添加圖片噪點。先說思路:創建圖片A做為背景,其次創建圖片B,在圖片B畫上驗證碼文字,然后將圖片B拆分成若干部分畫到圖片A上。打個比方,好比是把一張畫縱向平均裁成若干份,然后再上下交錯着粘到另一張白紙上。如果隨意的上下交錯排列,看到的八成就是一片亂七八糟的玩意兒,這里不妨按照一個曲線變化的規律來排列,我選擇的是正弦曲線。

  步驟:

  1、新建一般處理程序TestCodeHandler.ashx,先定義一個隨機生成驗證碼文字的方法,如下:

        /// <summary>
        /// 隨機生成驗證碼
        /// </summary>
        /// <returns></returns>
        public string GetTestCode()
        {
            Random r = new Random();

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < 5; i++)
            {
                int n = r.Next(65, 91);
                sb.Append((char)n);
            }
            return sb.ToString();
        }    

  2、在ProcessRequest方法中,確定輸出文件的類型。  

 context.Response.ContentType = "image/jpeg";

  3、引用命名空間System.Drawing和using System.Drawing.Imaging生成驗證碼圖片。

 

            using (Image img = new Bitmap(85, 40))//背景圖片
            {
                using (Image fontImg = new Bitmap(84, 38))//預先畫驗證碼的臨時圖片
                {
                    //先將驗證碼畫到臨時圖片fontImg上
                    using (Graphics fontGraphic = Graphics.FromImage(fontImg))
                    {
                        fontGraphic.Clear(Color.White);//將畫布塗白
                        //畫驗證嗎
                        fontGraphic.DrawString(GetTestCode(), new Font("宋體", 18, FontStyle.Italic | FontStyle.Bold), Brushes.Black, new PointF(4, 4));
                    }
                    //將臨時驗證碼圖片fontImg分成若干份畫到背景圖片img上
                    using (Graphics g = Graphics.FromImage(img))
                    {
                        g.Clear(Color.White);//將畫布塗白                       
                        int sum = 60;//分成60份
                        int niu = 6;//上下最多偏移10像素
                        float x = 0, y = 1;//從臨時圖片fontImg選取矩形區域的起始坐標
                        //從臨時圖片fontImg選取矩形區域的寬度,由於有背景圖片映襯,這里只確定寬度                        
                        float width = ((float)fontImg.Width) / sum;
                        //依次把臨時圖片fontImg各部分畫到背景圖片上                       
                        for (int i = 0; i < sum; i++)
                        {                            
                            //獲取當前部分的正弦值,計算上下偏移量。但這樣會使驗證碼的扭曲單一
                            float rate = (float)Math.Sin(360 * 1.0 / sum * i / 180 * Math.PI) * niu;
                            //如果使用隨機數,會有不同的變化
                            //Random r = new Random(DateTime.Now.Millisecond);
                            //float rate = (float)Math.Sin(360 * 1.0 / sum * i / 180 * Math.PI) * r.Next(1,niu);

                            //把臨時圖片fontImg當前部分畫到背景圖片上
                            g.DrawImage(fontImg, new Rectangle(x==0?1:(int)x, (int)y, img.Width, img.Height - 2), x, y * rate, width, fontImg.Height, GraphicsUnit.Pixel);
                            //依次改變橫坐標的下一個位置
                            x += width;                           
                            
                        }
                        //為背景圖片畫邊框
                        g.DrawRectangle(new Pen(Brushes.Black), new Rectangle(0, 0, img.Width - 1, img.Height - 1));
                    }
                }
                //將背景圖片保存到輸出流
                img.Save(context.Response.OutputStream, ImageFormat.Jpeg);

 

  4、測試。新建html頁面,添加<img>標簽,令src屬性指向TestCodeHandler.ashx,並為它的onclick事件注冊方法,實現點擊切換圖片的效果。如下:

 

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
        function change() {
            document.getElementById("img").src = "TestCodeHandler.ashx?id=" + new Date().getTime();
        }
    </script>
</head>
<body>
    <img id="img" src="TestCodeHandler.ashx"  onclick="change()"/>
</body>
</html>

 

  5、效果如下: 

     

  恕在下能力一般,水平有限,也只能實現上面的效果。若有高人看到此文,發現有不到之處,還望不吝賜教。

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM