pg has asked for the wisdom of the Perl Monks concerning the following question:

Is there a perl module for win32, that I can use it to capture all pixels in a certain area on the screen, I mean the RGB, or something like this.

Replies are listed 'Best First'.
Re: capture what's on the screen
by BrowserUk (Patriarch) on Feb 01, 2003 at 23:36 UTC

    As is, this captures a bitmap of the whole screen. Use "%{PrtScn}" for just the current window. Interpreting and manipulating the bitmap captured is over to you. You may find this document useful. The site's pretty damn useful too. Qudos to PodMaster for a reference to that some time back.

    #! perl -slw #use Win32::Bitmap; use strict; use Win32::GuiTest qw[SendKeys]; use Win32::Clipboard; my $cb = Win32::Clipboard->new(); $cb->Empty(); SendKeys( "+{PRTSCR}" ); $cb->WaitForChange(); my $image = $cb->GetBitmap() or die 'No bitmap there'; print 'Total size:', length $image; my %BMPinfo; @BMPinfo{ ( '01UINT type', #! 2 '02DWORD size', #! 4 '03UINT Reserved1', #! 2 '04UINT Reserved2', #! 2 '05DWORD Offset', #! 4 '06DWORD biSize', #! 4 '07LONG biWidth', #! 4 '08LONG biHeight', #! 4 '09WORD biPlanes', #! 2 '10WORD biBitCount', #! 2 '11DWORD biCompression', #! 4 '12DWORD biSizeImage', #! 4 '13LONG biXPelsPerMeter', #! 4 '14LONG biYPelsPerMeter', #! 4 '15DWORD biClrUsed', #! 4 '16DWORD biClrImportant', #! 4 ) #!54 } = unpack 'A2 L S S L L V V s s L L V V L L', substr $image, 0, 54; printf '%23s : %s'.$/, $_, $BMPinfo{$_} for sort keys %BMPinfo; __END__ C:\test>231894 Total size:1572918 01UINT type : BM 02DWORD size : 1572918 03UINT Reserved1 : 0 04UINT Reserved2 : 0 05DWORD Offset : 54 06DWORD biSize : 40 07LONG biWidth : 1024 08LONG biHeight : 768 09WORD biPlanes : 1 10WORD biBitCount : 16 11DWORD biCompression : 3 12DWORD biSizeImage : 1572864 13LONG biXPelsPerMeter : 0 14LONG biYPelsPerMeter : 0 15DWORD biClrUsed : 0 16DWORD biClrImportant : 0

    Examine what is said, not who speaks.

    The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.

Re: capture what's on the screen
by mattriff (Chaplain) on Feb 01, 2003 at 21:41 UTC
    I found this mailing list post, which describes something pretty similar to what you are looking for.

    Of course, that's capturing the whole screen (printscreen) or the active window (alt-printscreen). Once you had that, though, you could use ImageMagick to crop to the section you need. (That's one way, anyway. TIMTOWTDI, I'm sure.)

    - Matt Riffle

      This is not quite what I am looking for. I want the capturing fully controled by my program, without any human interaction, so printscreen does not work (I don't press buttons ;-)

      However to capture the whole screen instead of an area is okay with me, I can process it after.

      Update

      Cool, I will take a look, thanks.
        My reading of that code (and I've never used any of the Win32 modules ever, so YMMV) was that you didn't press anything -- it simulated the keystroke for you.

        The part I'm talking about is:

        # press the key!! $key->Call(0x2C, 0x45, 0x01, 0); #simulate a "printscrn" key press $key->Call(0x2C, 0x45, 0x03, 0); # & release

        - Matt Riffle

Re: capture what's on the screen
by PodMaster (Abbot) on Feb 02, 2003 at 04:34 UTC
    *grin*

    In my exploration of wxPerl, I came up with the following , it has extra "fluff", but you can clean it to suit you

    package ScreenShot; use Wx qw[ :everything ]; use Wx::Colour qw[ :everything ]; use Wx::Event qw[ :everything ]; use Wx::App; use base qw[Wx::App]; sub OnInit { my( $self )=@_; if(1){ # my $w = new Wx::Frame(undef,-1,"crap",[-1,-1,],[-1,-1],wxTRAN +SPARENT_WINDOW ); my $w = new Wx::Frame(undef,-1,"crap",[-1,-1,],[-1,-1],wxTRANS +PARENT_WINDOW ); # my $w = new Wx::Frame(undef,-1,"crap",[-1,-1,],[-1,-1],wxSTAY +_ON_TOP); # my $w = new Wx::Frame(undef,-1,"crap",[-1,-1,],[-1,-1],wxNO_B +ORDER | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION ) +; # my $w = new Wx::Frame(undef,-1,"crap",[-1,-1,],[-1,-1],wxSTAY +_ON_TOP|wxDEFAULT_FRAME_STYLE|wxNO_BORDER); EVT_PAINT( $w, sub { my($s,$e)=@_; my $dc = Wx::PaintDC->new($s); # must create, to stop crap $self->PaintThisBitch; return 0; }); $w->Show(1); $w->CaptureMouse(); $w->Clear(); $w->Refresh; } EVT_MOTION( $self, sub {warn"@_"}); return 1; } sub TakeScreenshot { my($self, $file ) = @_; $file ||= 'test.bmp'; my $screen = Wx::ScreenDC->new(); my( $x, $y) = $screen->GetSizeWH(); my $bitmap = Wx::Bitmap->new($x,$y,-1); my $memory = Wx::MemoryDC->new(); $memory->SelectObject( $bitmap ); $memory->Blit(0,0,$x,$y, $screen, 0, 0); $bitmap->SaveFile( $file , wxBITMAP_TYPE_BMP ) ; } sub PaintThisBitch { my $screen = Wx::ScreenDC->new(); $screen->SetBackgroundMode( wxTRANSPARENT ); $screen->SetFont(Wx::Font->new( 40, wxDECORATIVE, wxNORMAL, wxBOLD +, 0 )); for(1..255){ my $c = $_; $screen->SetTextForeground( Wx::Colour->newRGB(0,0,$c) +); $screen->DrawRotatedText("wxPerl",410 ,400 ,$_); $screen->DrawRotatedText("wxPerl and PodMaster",410 ,5 +00 ,0); $screen->DrawRotatedText("are messing up your screen", +410 ,550 ,0); select undef, undef, undef, 0.0001; } for(1..255){ my $c = $_; $screen->SetTextForeground( Wx::Colour->newRGB(0,$c,0) +); $screen->DrawRotatedText("wxPerl",410 ,400 ,$_); $screen->DrawRotatedText("wxPerl and PodMaster",410 ,5 +00 ,0); $screen->DrawRotatedText("are messing up your screen", +410 ,550 ,0); select undef, undef, undef, 0.0001; } for(1..255){ my $c = $_; $screen->SetTextForeground( Wx::Colour->newRGB($c,0,0) +); $screen->DrawRotatedText("wxPerl",410 ,400 ,$_); $screen->DrawRotatedText("wxPerl and PodMaster",410 ,5 +00 ,0); $screen->DrawRotatedText("are messing up your screen", +410 ,550 ,0); select undef, undef, undef, 0.0001; } return 0; } package main; my $i = ScreenShot->new; $i->TakeScreenshot('testor.bmp'); $i->PaintThisBitch; $i->MainLoop; __END__ wxScreenDC context = wxClientDC( self ) memory = wxMemoryDC( ) x,y = self.GetClientSizeTuple() bitmap = wxEmptyBitmap( x,y, -1 ) memory.SelectObject( bitmap ) memory.Blit( 0,0,x,y, context, 0,0) memory.SelectObject( wxNullBitmap) bitmap.SaveFile( "test.bmp", wxBITMAP_TYPE_BMP )


    MJD says you can't just make shit up and expect the computer to know what you mean, retardo!
    ** The Third rule of perl club is a statement of fact: pod is sexy.