Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Screen Scraping with C#?

Posted on 2004-09-10
7
Medium Priority
?
738 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Suggested Courses

636 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