淘宝验证码破解之轮廓线

现在的验证码已经不是什么花哨的复杂背景了,而趋于背景单一,但字体扭曲,粘连,加上和字体同样颜色的干扰线,所以这个发展趋势就像武功练到一定境界时反而招式简单,却威力巨大。有句话叫做什么来着--返璞归真。

看看淘宝的验证码:让人纠结吧。

 

下面开始我们的破解之旅:淘宝验证码破解之轮廓线。

先从指定连接获取验证码图片:

//获取验证码
        private Bitmap GetCode(string url)
        {
          
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            System.IO.Stream responseStream = ((HttpWebResponse)request.GetResponse()).GetResponseStream();
            Image original = Image.FromStream(responseStream);

          
             
               
                Bitmap bitMap = new Bitmap(original);
              
                responseStream.Close();
                return bitMap;

        }

//图片拷贝

由于我们建立的对象是引用类型。所以得用拷贝函数。

private Bitmap CopyImg(Bitmap img)
        {
            int W = img.Width;
            int H = img.Height;
            Bitmap NewImg = new Bitmap(W, H);
            for (int y = 0; y < H; y++)
            {
                for (int x = 0; x < W; x++)
                {
                    Color C = img.GetPixel(x, y);

                    NewImg.SetPixel(x, y, C);
                }
            }
            return NewImg;
        }


        //图象二值化
        public Bitmap BitmapToHead(Bitmap Timg)
        {
            Bitmap img = CopyImg(Timg);
            int W = img.Width;
            int H = img.Height;
           
            for (int y = 0; y < H;y++ )
            {
                for(int x=0;x<W;x++)
                {
                Color c = img.GetPixel(x, y);
                int luma = (int)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11);//转换灰度的算法
                img.SetPixel(x, y, Color.FromArgb(luma, luma, luma));


            }
           }

            for(int y = 0; y < H;y++){

                for (int x = 0; x < W; x++)
                {

                  
                Color c = img.GetPixel(x, y);
                if (c.R >= 120)   //设置一个合适的临界值 大于等于临界值设为白色,小于临界值为黑色
                    img.SetPixel(x, y, Color.FromArgb(255, 255, 255));
                else img.SetPixel(x, y, Color.FromArgb(0, 0, 0));
                }
            }
            return img;
          
        }

下面就是关键算法了。跟踪轮廓线:

//轮廓线算法

private Bitmap ContourFollowing(Bitmap Timg)
        {
            Bitmap img = CopyImg(Timg);
            int W = img.Width-1;
            int H = img.Height-1;
            for (int y = 0; y <=H; y++)
            {
                for (int x = 0; x <=W; x++)
                {

                    if (y == 0 && x == 0)
                    {
                        //break;

                    }
                    else if (y == 0 && x > 0 && x < W)
                    {
                       // break;

                    }
                    else if (y == 0 && x == W)
                    {
                       //break;

                    }

                    else if (y > 0 && y < H && x == 0)
                    {
                       // break;

                    }
                    else if (x == 0 && y == H)
                    {
                        //break;

                    }
                    else if (x > 0 && x < W && y == H)
                    {
                        //break;

                    }
                    else if (x == W && y == H)
                    {
                        //break;

                    }
                    else if (x == W&& y > 0 && y < H)
                    {
                        //break;

                    }
                    else
                    {
                       Color Cm = img.GetPixel(x, y);
                        Color[] Ccenter = new Color[] { img.GetPixel(x - 1, y), img.GetPixel(x, y - 1), img.GetPixel(x, y + 1), img.GetPixel(x + 1, y) };

                       
                        int flag = 0;
                        if (Cm.R == 0)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                if (Ccenter[i].R==0||Ccenter[i].R==100)
                                {

                                    flag++;
                                }
                            }
                        }
                       
                        if (flag == 4)
                        {
                          
                            img.SetPixel(x, y, Color.FromArgb(100, 100, 100));
                        }
                       

                    }


                }

 

            }

            for (int y = 0; y < H; y++)
            {

                for (int x = 0; x < W; x++)
                {


                    Color c = img.GetPixel(x, y);
                    if (c.R == 100)   
                        img.SetPixel(x, y, Color.FromArgb(255, 255, 255));
                  
                }
            }
            return img;
        }

下面函数调用,画出轮廓线。

private void button1_Click(object sender, EventArgs e)
        {
            string url = textBox4.Text;
            //Bitmap Map =GetCode(url);
            Bitmap Mapp = CopyImg(GetCode1(url));
            Bitmap Map1 = BitmapToHead(Mapp);
            Bitmap Fuck = CopyImg(Map1);
            Bitmap Map2 = ContourFollowing(Fuck);

            pictureBox3.Image = Map1;

            pictureBox4.Image = Map2;


        }

 

posted @ 2010-06-01 18:17  zxgdm  阅读(2925)  评论(7编辑  收藏  举报