예제 #1
0
        public bool Adjacent(Letter l)
        {
            foreach (Point p in l.Pixels)
            {
                if (Adjacent(p))
                {
                    return true;
                }
            }

            return false;
        }
예제 #2
0
        public bool MergePixels(Letter l, Bitmap image)
        {
            // find out resulting width, if too great abort merge
            int min = MinX < l.MinX ? MinX : l.MinX;
            int max = MaxX > l.MaxX ? MaxX : l.MaxX;

            if (max - min + 1 > MAX_LETTER_WIDTH)
            {
                return false;
            }

            MinX = min;
            MaxX = max;
            MinY = MinY < l.MinY ? MinY : l.MinY;
            MaxY = MaxY > l.MaxY ? MaxY : l.MaxY;

            // add all of the pixels of the merged letter
            pixels.AddRange(l.Pixels);
            // change their color
            /*foreach (Point p in l.Pixels)
            {
                image.SetPixel(p.X, p.Y, Color);
            }*/

            return true;
        }
예제 #3
0
        private Bitmap Captcha()
        {
            Bitmap image = new Bitmap(Image.FromFile(file));
            List<Letter> toRemove = new List<Letter>();

            for (int y = 0; y < image.Height; y++)
            {
                for (int x = 0; x < image.Width; x++)
                {
                    Color c = image.GetPixel(x, y);
                    if (c.R < 70 && c.G < 70 && c.B < 70)
                    {
                        image.SetPixel(x, y, Color.FromArgb(255, 255, 0, 0));
                    }
                    else if (c.R < 163 && c.G < 163 && c.B < 163)
                    {
                        //image.SetPixel(x, y, Color.FromArgb(255, 0, 255, 0));
                        // check if point is adjacent to any of the points in the existing letters
                        Point p = new Point(x, y);
                        int letter = -1;
                        List<int> close = new List<int>();
                        for (int i = -1; i <= 1; i++)
                        {
                            for (int j = -1; j <= 1; j++)
                            {
                                if (i == 0 && j == 0) continue;
                                string key = (x + i) + "," + (y + j);
                                if (dic.ContainsKey(key))
                                {
                                    if (letter != -1 && letter != dic[key])
                                    {
                                        close.Add(dic[key]);
                                        continue;
                                    }
                                    letter = dic[key];
                                }
                            }
                        }

                        if (letter == -1)
                        {
                            // add new letter
                            Letter l = new Letter();
                            l.MinX = p.X;
                            l.MaxX = p.X;
                            l.MinY = p.Y;
                            l.MaxY = p.Y;
                            l.Pixels.Add(p);
                            dic[p.X + "," + p.Y] = letters.Count;
                            //l.Color = cols[letters.Count % cols.Length];
                            //image.SetPixel(x, y, l.Color);
                            letters.Add(l);
                            continue;
                        }

                        if (p.X < letters[letter].MinX)
                            letters[letter].MinX = p.X;
                        if (p.Y < letters[letter].MinY)
                            letters[letter].MinY = p.Y;

                        if (p.X > letters[letter].MaxX)
                            letters[letter].MaxX = p.X;
                        if (p.Y > letters[letter].MaxY)
                            letters[letter].MaxY = p.Y;

                        letters[letter].Pixels.Add(p);
                        dic[p.X + "," + p.Y] = letter;

                        // merge all other nearby letters with this one
                        foreach (int l in close)
                        {
                            if (letters[letter].MergePixels(letters[l], image))
                            {
                                toRemove.Add(letters[l]);
                                foreach (Point pp in letters[l].Pixels)
                                {
                                    dic[pp.X + "," + pp.Y] = letter;
                                }
                            }
                        }
                    }
                }
            }

            foreach (Letter l in toRemove)
            {
                letters.Remove(l);
            }

            // complexity: O(n)
            // min: 151ms, max: 245ms, avg: 177.147058823529ms

            Random r = new Random((int)(DateTime.Now.Ticks / 1000));

            // highlight each individual letter by assigning a separate color
            for (int i = 0; i < letters.Count; i++)
            {
                letters[i].Color = Color.FromArgb(255, (r.Next(0, 255) + i * 2) % 255,
                                                  (r.Next(0, 255) + i * 3) % 255,
                                                  (r.Next(0, 255) + i * 5) % 255); //cols[i%cols.Length];
                foreach (Point p in letters[i].Pixels)
                {
                    image.SetPixel(p.X, p.Y, letters[i].Color);
                }
            }

            // draw the whole text image
            Invoke(new MethodInvoker(delegate
            {
                Graphics g = Graphics.FromHwnd(Handle); // real graphics
                g.DrawImage(image, 540, 80);

                g.Dispose();
            }));
            /*
            for (int i = 0; i < letters.Count; i++)
            {
                // create new image containing just this letter, white on black
                Image single = letters[i].CreateImage();

                // prompt user to read letter, if 'bad' is inputted, letter was not properly recognized
                Invoke(new MethodInvoker(delegate
                {
                    Graphics g = Graphics.FromHwnd(Handle); // real graphics
                    g.DrawImage(new Bitmap(100, 40, PixelFormat.Format24bppRgb), 540, 30);
                    g.DrawImage(single, 540, 30);

                    g.Dispose();
                    textBox2.Text = "";
                    textBox2.Enabled = true;
                    textBox2.Focus();
                }));

                while (textBox2.Enabled)
                {
                    Thread.Sleep(100);
                }

                // save individual letter to jpg file
                if (textBox2.Text.ToLower() != "bad")
                {
                    if (!Directory.Exists(LETTER_PATH + textBox2.Text))
                    {
                        Directory.CreateDirectory(LETTER_PATH + textBox2.Text);
                    }
                    for (int j = 0; ; j++)
                    {
                        if (File.Exists(LETTER_PATH + textBox2.Text + "\\" + j +
                                    ".jpg")) continue;

                        single.Save(LETTER_PATH + textBox2.Text + "\\" + j +
                                    ".jpg");
                        break;
                    }
                }
            }
            */
            return image;
        }