0

Is there any way to capture or copy the loaded image from the web browser to the picture box?

The image I am tring to copy is "captcha" image and every request it will change. I need the loaded image in the web browser be the same as the picture box.

I have tried to split the img tag and request the image again. It worked but the picture box image was not the same as the one the web browser shows.

Here is what I have done so far. It contains one web browser, one picture box, one text box, and one button

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO;
using System.Net;

namespace arman_dobare_kir_mishavad
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string str2 = webBrowser1.DocumentText;
            string[] strArray2;
            strArray2 = Regex.Split(Regex.Split(str2, "<img id=\"content1_imgCaptcha\" src=\"")[1], "\"");
            textBox1.Text = strArray2[0];
            this.pictureBox1.ImageLocation = "http://www.hashkiller.co.uk" + strArray2[0];
            return;
        }

        public void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {

        }
    }
}
gunr2171
  • 16,104
  • 25
  • 61
  • 88
sci3nt15t
  • 93
  • 1
  • 8

1 Answers1

8

This i quite a tricky one that took me months to solve. First things first. As you have discovered nearly all captcha images are dynamically generated images, this means that each time you request the image, even though the url (src tag) is the same, a new captcha image will always generated.

Your best bet to solve this is by "snipping" the already loaded captcha image out of your webbrowser. Trust me, this is the best way, if not the only way.

The good news is, it can easily be done with a built in method

webBrowser.DrawToBitmap(Bitmap,Rectangle)

My Sample Code: (how to use webbrowser.DrawToBitmap for an specific Element)

    private void button1_Click(object sender, EventArgs e)
    {
        int CaptchaWidth = getXoffset(webBrowser1.Document.GetElementById("Captch-Element-Name"));
        int CaptchaHeight = getYoffset(webBrowser1.Document.GetElementById("Captch-Element-Name"));

        Bitmap bitmap = new Bitmap(CaptchaWidth, CaptchaHeight);
        webBrowser1.DrawToBitmap(bitmap, new Rectangle(0, 0, CaptchaWidth, CaptchaHeight));

        //now load the image into your pictureBox (you might need to convert the bitmap to a image)
    }

    //Methods to get Co-ordinates Of an Element in your webbrowser
    public int getXoffset(HtmlElement el)
    {
        int xPos = el.OffsetRectangle.Left;
        HtmlElement tempEl = el.OffsetParent;
        while (tempEl != null)
        {
            xPos += tempEl.OffsetRectangle.Left;
            tempEl = tempEl.OffsetParent;
        }
        return xPos;
    }

    public int getYoffset(HtmlElement el)
    {
        int yPos = el.OffsetRectangle.Top;
        HtmlElement tempEl = el.OffsetParent;
        while (tempEl != null)
        {
            yPos += tempEl.OffsetRectangle.Top;
            tempEl = tempEl.OffsetParent;
        }
        return yPos;
    }

So, the bad news is that c# has a annoying little bug in the drawtobitmap method (which is mentioned on the msdn site). What happens is sometimes a blank image will be returned when you run it.... yeah... not really what you want when you trying to crack Captchas right!

Luckily! Another stackOverflow user and i spent months working on a bug free version of this method that makes use of native GDI+.

And it works perfectly, so if drawtobitmap doesn't work the way you expect, here is an alternative.

Sample:

    [DllImport("user32.dll")]
    public static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, uint nFlags);

    public Bitmap CaptureWindow(Control ctl)
    {
        //Bitmap bmp = new Bitmap(ctl.Width, ctl.Height);  // includes borders
        Bitmap bmp = new Bitmap(ctl.ClientRectangle.Width, ctl.ClientRectangle.Height);  // content only
        using (Graphics graphics = Graphics.FromImage(bmp))
        {
            IntPtr hDC = graphics.GetHdc();
            try { PrintWindow(ctl.Handle, hDC, (uint)0); }
            finally { graphics.ReleaseHdc(hDC); }
        }
        return bmp;
    }

So you'll simply call: CaptureWindow(webBrowser1); This will return a image of the entire webbrowser, then just snip-out the section containing the captcha image.

You can view my questions were i had the similar problems here (most weren't even answered):

Extracting a image from a WebBrowser Control

Screenshot method generates black images

Reset Webbrowser control to update settings

Now that you have the captcha images you'll need to decrypt them. So ask another question, send me the link and ill share my methods. Im glad you didnt have to endure my nightmare. Don't forget to mark this as a solution, and as useful!

Community
  • 1
  • 1
Msegling
  • 365
  • 3
  • 12