[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Screen Scraping with C#?

Posted on 2004-09-10
7
Medium Priority
?
742 Views
Last Modified: 2011-09-20
Hi,

  I like to play Hearts on MSN Gaming Zone.  I would like to write a program that tracks the different cards that have been played for each round.  So, the question is how do I screen scrape a graphical window using C#?

The steps in my mind would consist of something like:

1) Get the device context of the foreign (Hearts) window
2) Capture the graphic bits in a well-defined, never changing location
3) Compare those graphics (the face of the card) with a library of 52 cards looking for a match

Can anyone help me with this?  Never mind if it is cheating or not, it is a way for me to learn more about graphics and programming.  I would consider giving more points if 500 is not enough for this challenge.

Thanks

Robert
0
Comment
Question by:rmyhre
  • 4
  • 2
7 Comments
 
LVL 4

Accepted Solution

by:
thedude112286 earned 2000 total points
ID: 12030163
http://www.c-sharpcorner.com/Code/2003/Dec/ScreenCapture.asp was used extensively to develop this

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

class GDI32
{
      [DllImport("GDI32.dll")]
      public static extern bool BitBlt(int hdcDest,int nXDest,int nYDest,
                                       int nWidth,int nHeight,int hdcSrc,
                                       int nXSrc,int nYSrc,int dwRop);
      [DllImport("GDI32.dll")]
      public static extern int CreateCompatibleBitmap(int hdc,int nWidth,
                                                       int nHeight);
      [DllImport("GDI32.dll")]
      public static extern int CreateCompatibleDC(int hdc);
      [DllImport("GDI32.dll")]
      public static extern bool DeleteDC(int hdc);
      [DllImport("GDI32.dll")]
      public static extern bool DeleteObject(int hObject);
      [DllImport("GDI32.dll")]
      public static extern int GetDeviceCaps(int hdc,int nIndex);
      [DllImport("GDI32.dll")]
      public static extern int SelectObject(int hdc,int hgdiobj);
 

class User32
{
      [DllImport("User32.dll")]
      public static extern int FindWindow(string lpClassName, string lpWindowName);
      [DllImport("User32.dll")]
      public static extern int GetWindowDC(int hWnd);
      [DllImport("User32.dll")]
      public static extern int ReleaseDC(int hWnd,int hDC);
}
 

class Example
{
        string className, windowText;
      
        //the className parameter must be the name of the target window's class
        //and windowText must be the text of the target window - if you've never done
        //straight Win32 API programming and don't understand this concept, ask me
      public void CaptureScreen(string fileName,ImageFormat imageFormat, string className, string windowText)
      {
                  this.className = className;
                this.windowText = windowText;
                  int hdcSrc = User32.GetWindowDC(User32.FindWindow(className, windowText));
            int hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
            int hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc),
                                                                             GDI32.GetDeviceCaps(hdcSrc,8),
                                                                             GDI32.GetDeviceCaps(hdcSrc,10));
            GDI32.SelectObject(hdcDest,hBitmap);
            // set the nWidth, nHeight, nXSrc, and nYSrc parameters of BitBlt to whatever portion of the window you want
            GDI32.BitBlt(hdcDest,0,0,GDI32.GetDeviceCaps(hdcSrc,8),
                            GDI32.GetDeviceCaps(hdcSrc,10),
                            hdcSrc,0,0,0x00CC0020);
            Bitmap bitmap = GetManagedBitmap(hBitmap,fileName,imageFormat);
            Cleanup(hBitmap,hdcSrc,hdcDest);
            
                  //do whatever operations you want to do on bitmap
      }
      private void Cleanup(int hBitmap,int hdcSrc,int hdcDest)
      {
            User32.ReleaseDC(User32.FindWindow(className, windowText),hdcSrc);
            GDI32.DeleteDC(hdcDest);
            GDI32.DeleteObject(hBitmap);
      }      

      private Bitmap GetManagedBitmap(int hBitmap,string fileName,ImageFormat imageFormat)
      {
            Bitmap image =
            new Bitmap(Image.FromHbitmap(new IntPtr(hBitmap)),
                       Image.FromHbitmap(new IntPtr(hBitmap)).Width,
                       Image.FromHbitmap(new IntPtr(hBitmap)).Height);
            return image;
      }
}
0
 

Author Comment

by:rmyhre
ID: 12030252
Wow... a lot to disect there... thanks.

What I don't see is step 3... how to compare the two images?

Any help?
0
 
LVL 4

Expert Comment

by:thedude112286
ID: 12034486
I'm going away for the weekend but I'll look into comparing the images when I get back.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 4

Expert Comment

by:thedude112286
ID: 12039977
All I can think of is to try:

if ( screenBitmap == storedBitmap )
    //match

That should work fine as long as you get the EXACT same area of the window when you store the bitmap and when you get a bitmap to compare.
0
 
LVL 4

Expert Comment

by:thedude112286
ID: 12039980
Actually, I'm not sure about how == works on Bitmaps.  You may need to examine each bit to see if it is equal.
0
 

Author Comment

by:rmyhre
ID: 12044678
I figured it out over the weekend.  Basically I dump the bitmap into a memory stream and then convert the memory stream into a byte array.  Finally, I just iterate through the array checking each value to ensure that they are the same in both the stored image and the scanned image.

Works pretty slick  :)
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article series is supposed to shed some light on the use of IDisposable and objects that inherit from it. In essence, a more apt title for this article would be: using (IDisposable) {}. I’m just not sure how many people would ge…
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
When cloud platforms entered the scene, users and companies jumped on board to take advantage of the many benefits, like the ability to work and connect with company information from various locations. What many didn't foresee was the increased risk…
Suggested Courses
Course of the Month17 days, 16 hours left to enroll

831 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question