From: ··············@yahoo.it
Subject: how to get a bitmap from the screen and then inside lisp?
Date: 
Message-ID: <d11c55d1-fd87-42ee-b139-bffeccf0e115@a37g2000pre.googlegroups.com>
Is there a fast way to get the screen content (or part of it) inside
the lisp workspace, maybe as an array? I experiment with pattern
matching and would like to search the content of the screen or some
area of it to find certain patterns.

Until yet I've used some (non lisp) programs to take a shot of the
screen, save it to hard disk and read it in again into the lisp
workspace. That is quiet slow ... no wonder!

I've tried several times to install openGL or GTK+ didn't get until
the end, errors with the cffi interface or my lisp acl 7 is not
compatible ... . There must be easier solutions, than to shoot with
canons on sparrows!

Any recommendations for a win user?
c.

ps.: acl has functions to do this (also slow) but sooner or later I
would like to switch to open source.

From: George Neuner
Subject: Re: how to get a bitmap from the screen and then inside lisp?
Date: 
Message-ID: <708dk49lpeabooupmefv7ikfbh6e6cgsvm@4ax.com>
On Mon, 15 Dec 2008 09:39:14 -0800 (PST), ··············@yahoo.it
wrote:

>Is there a fast way to get the screen content (or part of it) inside
>the lisp workspace, maybe as an array? I experiment with pattern
>matching and would like to search the content of the screen or some
>area of it to find certain patterns.
>
>Until yet I've used some (non lisp) programs to take a shot of the
>screen, save it to hard disk and read it in again into the lisp
>workspace. That is quiet slow ... no wonder!
>
>I've tried several times to install openGL or GTK+ didn't get until
>the end, errors with the cffi interface or my lisp acl 7 is not
>compatible ... . There must be easier solutions, than to shoot with
>canons on sparrows!
>
>Any recommendations for a win user?
>c.
>
>ps.: acl has functions to do this (also slow) but sooner or later I
>would like to switch to open source.

A bit off topic, but who cares 8-)

Getting pixels off the screen quickly is a bit complicated and you
have to do some decoding of Windows bitmap data structures.  You
probably should write your grab function in C and call it with CFFI.

If you're pattern matching, it's probably best to separate the color
planes - pattern matching on color is tough and you'll probably want
to experiment with different ways of calculating power.

Windows uses a device independent  R<<16|G<<8|B color pixel internally
and you'll get that from most application windows, but if you copy
directly from the screen it could be pixel or planar depending on the
display board.

I didn't have any ready code to show you, so I quickly hacked up the
following.  It does _NO_ error checking except shockingly fatal, but
it shows the basic ideas.  Planar displays are left as an exercise.
Be sure to read up on the Windows GDI and the functions and structures
used.  Adding traps for all the possible errors will likely double the
length of the code.


------------------------------------------------------------
include <windows.h>

void GetWindowPixels( char *windowName,
                      int x, int y, int w, int h, 
                      int *R, 
                      int *G, 
                      int *B )
{
HWND window;
HDC  winDC, tmpDC;
HBITMAP bitmap;
BITMAP  info;
RGBTRIPLE *rgb;
RGBQUAD   *rgba;
int     count;
BYTE    *pixels;

  // alloc buffer
  pixels = (BYTE*) calloc( h * w, sizeof(RGBQUAD) );
  
  // get the window handle
  window = NULL;
  if ( windowName != NULL )
    {
    window = FindWindow( NULL, windowName );
    if ( window == NULL ) return;
    }
  
  // get window DC (or screen DC if window is NULL)
  winDC = GetDC(window);
  if (winDC == NULL) return;

  // create temp DC
  tmpDC = CreateCompatibleDC(winDC);

  // create bitmap
  bitmap = CreateCompatibleBitmap(winDC, w,h );

  // copy desktop ROI to bitmap
  SelectObject( tmpDC, bitmap );
  BitBlt( tmpDC, 0,0,w,h , winDC, x,y , SRCCOPY );
  SelectObject( tmpDC, (HBITMAP) NULL);

  // extract pixels from bitmap.  
  // TODO: handle planar bitmaps
  GetObject( bitmap, sizeof(info), &info );
  switch ( info.bmBitsPixel )
    {
    case 24:
      count  = h * w * sizeof(RGBTRIPLE);
      break;
    case 32:
      count  = h * w * sizeof(RGBQUAD);
      break;
    }
  GetBitmapBits( bitmap, count, pixels );
     
  // extract colors for each pixel
  count = h * w;
  switch ( info.bmBitsPixel )
    {
    case 24:
      rgb = (RGBTRIPLE*) pixels;
      while ( --count >= 0 )
        {
        *R++ = rgb->rgbtRed;
        *G++ = rgb->rgbtGreen;
        *B++ = rgb->rgbtBlue;
        rgb++;
        }
      break;
    case 32:
      rgba = (RGBQUAD*) pixels;
      while ( --count >= 0 )
        {
        *R++ = rgba->rgbRed;
        *G++ = rgba->rgbGreen;
        *B++ = rgba->rgbBlue;
        rgba++;
        }
      break;
      }
                       
  // cleanup 
  if (pixels) free(pixels);
  if (bitmap) DeleteObject(bitmap);
  if (tmpDC)  DeleteDC(tmpDC);
  
  ReleaseDC(window,winDC);
}
------------------------------------------------------------


When you study the GDI, you'll encounter the function GetPixel and
wonder why I didn't use it.  The answer is that it's slower than
molasses for a moderate to large ROI.  GDI functions are system calls
and there is a fair amount of overhead for each call.  Even though the
bitmap BLiT is harder to set up, it's 1 BLiT call vs (10s of)
thousands of GetPixel calls.

George
From: GP lisper
Subject: Re: how to get a bitmap from the screen and then inside lisp?
Date: 
Message-ID: <slrngkeefu.2t2.spambait@phoenix.clouddancer.com>
> On Mon, 15 Dec 2008 09:39:14 -0800 (PST), ··············@yahoo.it
> wrote:
>
>>Is there a fast way to get the screen content (or part of it) inside
>>the lisp workspace, maybe as an array? I experiment with pattern
>>matching and would like to search the content of the screen or some
>>area of it to find certain patterns.
>>
>>Any recommendations for a win user?

There is the program "AutoIt" that can do this, you might track down
some info there.  The author is apparently friendly according to
reports.

** Posted from http://www.teranews.com **
From: ··············@yahoo.it
Subject: Re: how to get a bitmap from the screen and then inside lisp?
Date: 
Message-ID: <03df1e42-3210-4909-aed6-1dcfe3ddd00f@r15g2000prd.googlegroups.com>
On 16 Dez., 06:17, GP lisper <········@CloudDancer.com> wrote:
> > On Mon, 15 Dec 2008 09:39:14 -0800 (PST), ··············@yahoo.it
> > wrote:
>
> >>Is there a fast way to get the screen content (or part of it) inside
> >>the lisp workspace, maybe as an array? I experiment with pattern
> >>matching and would like to search the content of the screen or some
> >>area of it to find certain patterns.
>
> >>Any recommendations for a win user?
>
> There is the program "AutoIt" that can do this, you might track down
> some info there.  The author is apparently friendly according to
> reports.
>
> ** Posted fromhttp://www.teranews.com**

I know about autoit3, it is very nice and has a lot of additional
functions. Taking a bitmap from the screen is incredible fast, but how
to import it to lisp ... I'm stuck there.

by the way, for all lisp win users: autoit3 has all the functionality
lisp is DESPERATELY lacking (in one package). you can connect to it
via console, sockets or set up a "file listener".
c.
From: ··············@yahoo.it
Subject: Re: how to get a bitmap from the screen and then inside lisp?
Date: 
Message-ID: <f17ed0c1-43f7-46b3-a98a-f2b34b093963@v39g2000pro.googlegroups.com>
On 15 Dez., 23:27, George Neuner <········@comcast.net> wrote:
> On Mon, 15 Dec 2008 09:39:14 -0800 (PST), ··············@yahoo.it
> wrote:
>
>
>
>
>
> >Is there a fast way to get the screen content (or part of it) inside
> >the lisp workspace, maybe as an array? I experiment with pattern
> >matching and would like to search the content of the screen or some
> >area of it to find certain patterns.
>
> >Until yet I've used some (non lisp) programs to take a shot of the
> >screen, save it to hard disk and read it in again into the lisp
> >workspace. That is quiet slow ... no wonder!
>
> >I've tried several times to install openGL or GTK+ didn't get until
> >the end, errors with the cffi interface or my lisp acl 7 is not
> >compatible ... . There must be easier solutions, than to shoot with
> >canons on sparrows!
>
> >Any recommendations for a win user?
> >c.
>
> >ps.: acl has functions to do this (also slow) but sooner or later I
> >would like to switch to open source.
>
> A bit off topic, but who cares 8-)
>
> Getting pixels off the screen quickly is a bit complicated and you
> have to do some decoding of Windows bitmap data structures.  You
> probably should write your grab function in C and call it with CFFI.
>
> If you're pattern matching, it's probably best to separate the color
> planes - pattern matching on color is tough and you'll probably want
> to experiment with different ways of calculating power.
>
> Windows uses a device independent  R<<16|G<<8|B color pixel internally
> and you'll get that from most application windows, but if you copy
> directly from the screen it could be pixel or planar depending on the
> display board.
>
> I didn't have any ready code to show you, so I quickly hacked up the
> following.  It does _NO_ error checking except shockingly fatal, but
> it shows the basic ideas.  Planar displays are left as an exercise.
> Be sure to read up on the Windows GDI and the functions and structures
> used.  Adding traps for all the possible errors will likely double the
> length of the code.
>
> ------------------------------------------------------------
> include <windows.h>
>
> void GetWindowPixels( char *windowName,
>                       int x, int y, int w, int h,
>                       int *R,
>                       int *G,
>                       int *B )
> {
> HWND window;
> HDC  winDC, tmpDC;
> HBITMAP bitmap;
> BITMAP  info;
> RGBTRIPLE *rgb;
> RGBQUAD   *rgba;
> int     count;
> BYTE    *pixels;
>
>   // alloc buffer
>   pixels = (BYTE*) calloc( h * w, sizeof(RGBQUAD) );
>
>   // get the window handle
>   window = NULL;
>   if ( windowName != NULL )
>     {
>     window = FindWindow( NULL, windowName );
>     if ( window == NULL ) return;
>     }
>
>   // get window DC (or screen DC if window is NULL)
>   winDC = GetDC(window);
>   if (winDC == NULL) return;
>
>   // create temp DC
>   tmpDC = CreateCompatibleDC(winDC);
>
>   // create bitmap
>   bitmap = CreateCompatibleBitmap(winDC, w,h );
>
>   // copy desktop ROI to bitmap
>   SelectObject( tmpDC, bitmap );
>   BitBlt( tmpDC, 0,0,w,h , winDC, x,y , SRCCOPY );
>   SelectObject( tmpDC, (HBITMAP) NULL);
>
>   // extract pixels from bitmap.  
>   // TODO: handle planar bitmaps
>   GetObject( bitmap, sizeof(info), &info );
>   switch ( info.bmBitsPixel )
>     {
>     case 24:
>       count  = h * w * sizeof(RGBTRIPLE);
>       break;
>     case 32:
>       count  = h * w * sizeof(RGBQUAD);
>       break;
>     }
>   GetBitmapBits( bitmap, count, pixels );
>
>   // extract colors for each pixel
>   count = h * w;
>   switch ( info.bmBitsPixel )
>     {
>     case 24:
>       rgb = (RGBTRIPLE*) pixels;
>       while ( --count >= 0 )
>         {
>         *R++ = rgb->rgbtRed;
>         *G++ = rgb->rgbtGreen;
>         *B++ = rgb->rgbtBlue;
>         rgb++;
>         }
>       break;
>     case 32:
>       rgba = (RGBQUAD*) pixels;
>       while ( --count >= 0 )
>         {
>         *R++ = rgba->rgbRed;
>         *G++ = rgba->rgbGreen;
>         *B++ = rgba->rgbBlue;
>         rgba++;
>         }
>       break;
>       }
>
>   // cleanup
>   if (pixels) free(pixels);
>   if (bitmap) DeleteObject(bitmap);
>   if (tmpDC)  DeleteDC(tmpDC);
>
>   ReleaseDC(window,winDC);}
>
> ------------------------------------------------------------
>
> When you study the GDI, you'll encounter the function GetPixel and
> wonder why I didn't use it.  The answer is that it's slower than
> molasses for a moderate to large ROI.  GDI functions are system calls
> and there is a fair amount of overhead for each call.  Even though the
> bitmap BLiT is harder to set up, it's 1 BLiT call vs (10s of)
> thousands of GetPixel calls.
>
> George

thank you, for the quick answer. phuuuu ... . I'm new to C and
cffi ... I will try to get it work.
From: budden
Subject: Re: how to get a bitmap from the screen and then inside lisp?
Date: 
Message-ID: <c550bd4f-ccfd-4e10-87f5-7ce3a6a0b958@w1g2000prk.googlegroups.com>
Hi! If you can write an autoIt script which saves bitmap as a file,
you just can use files to exchange data. It works slower, but it is
much easier to develop.

Also you can use a simple file-based sychronization protocol. Lisp and
autoFit are not connected at all, but they use files and locks on them
to communicate. Opening a file for exclusive writing emulates an
exclusive lock. Precense of some special file means that lisp wants a
bitmap. autoFit runs in a loop and checks for that file periodically.
Bitmap itself is also passed via a file: autoIt saves a file, lisp
reads it. This protocol is rather slow, but it is very easy to
implement.

Also you can use mutexes for synchronization, but to use them you need
to install some portability library first. Mutexes are not
standartized in lisp, you should use portable libraries.

$5/hour cl freelancer
From: Tamas K Papp
Subject: Re: how to get a bitmap from the screen and then inside lisp?
Date: 
Message-ID: <6qnkk4Fddhh6U1@mid.individual.net>
On Mon, 15 Dec 2008 09:39:14 -0800, christophamort wrote:

> Is there a fast way to get the screen content (or part of it) inside the
> lisp workspace, maybe as an array? I experiment with pattern matching
> and would like to search the content of the screen or some area of it to
> find certain patterns.
> 
> Until yet I've used some (non lisp) programs to take a shot of the
> screen, save it to hard disk and read it in again into the lisp
> workspace. That is quiet slow ... no wonder!
> 
> I've tried several times to install openGL or GTK+ didn't get until the
> end, errors with the cffi interface or my lisp acl 7 is not compatible
> ... . There must be easier solutions, than to shoot with canons on
> sparrows!
> 
> Any recommendations for a win user?

I would just call an external program, and then read the bitmap.  But as 
a Linux user, I can't help you with the specifics.

Tamas