Loading ...
Sorry, an error occurred while loading the content.
 

Re: [perlguitest] How to get slice of window instead of whole thing? DibSect

Expand Messages
  • Nicole Sheldon
    I thought I might update this so that if anyone in the future wants to accomplish the same thing as me they can read this in the forum and be happy :) It turns
    Message 1 of 7 , Nov 11, 2004
      I thought I might update this so that if anyone in the
      future wants to accomplish the same thing as me they
      can read this in the forum and be happy :)

      It turns out that a Windows Device Independent Bitmap
      is fairly complicated. It is the standard image format
      for Windows. People from Microsoft like the WDIB image
      type because it is independent of the device it is on
      (duh). They also like it because they can write
      advanced image processing palettes much better than
      some other image types, and standardize them
      throughout Windows.

      One of the main problems a PERL programmer has to face
      in getting a DIB working is interacting with an
      Windows C API that contains the functions that allow
      direct access to the DIB's pixel values. This really
      sucks if you do not know C (like me).

      ON CPAN they have a module called "Inline C" that
      allows a programmer to write "C" functions directly in
      their PERL scripts and call them, pass refs, etc. This
      is super handy but took a long time to setup because
      it does not work without a C compiler and linker
      (cl.exe and link.exe). I ended up installing Visual
      Studio .NET, which includes VC7 (what you want) and
      after much tedious error correcting had the "hello
      world" program execute successfully. Drop me an email
      if you cannot resolve the errors associated with C
      INLINE.


      While the reality isn't really so pretty sounding, the
      goal is to expand the functionality already in
      perlguitest for handling DibSect's. The main problems
      I have with the existing functionality:

      1. Cannot open a WDIB and copy into a DibSect.
      2. bool DibSect::CopyWindow(hwnd) copies the entire
      window.
      3. bool DibSect::CopyClient(hwnd,[rect]) does not have
      any examples...what the heck is [rect]?? What is the
      difference between a window and a client? [IF ANYONE
      CAN ANSWER THIS PLEASE DO]


      And to accomplish this I am going to #include GDC.h
      into a PERL script using Inline C and use the already
      developed C functions to call the needed
      functionality, passing back and forth DibSect
      references, etc.


      Wish me luck! I will post again when finished.

      N







      --- snikki326 <snikki326@...> wrote:

      >
      >
      > Hello,
      >
      > I recently got GuiTest::DibSect working and was
      > impressed at how
      > easy it makes capturing screen images. Sometimes,
      > however, the
      > window (that you specify to capture an image of) is
      > quite large and
      > in reality you want to capture a small subset of
      > that window. If
      > this were possible we would dramatically reduce the
      > size of the
      > captured image and reduce overall image processing
      > time.
      >
      > I read on CPAN about the following functions:
      > <sample>
      > # Synopsis:
      >
      > $ds = new Win32::GuiTest::DibSect;
      > $ds->CopyWindow($w);
      > $ds->ToGrayScale();
      > $ds->SaveAs("bla.bmp");
      > $ds->ToClipboard();
      > # bool DibSect::CopyClient(hwnd,[rect])
      > # Copy a client area of given window (or possibly
      > its subset) into a
      > # given DibSect. The rectangle may be optionally
      > passed as a
      > # reference to 4-element array. To get the right
      > result make sure
      > # the window you want to copy is not obscured by
      > others.
      >
      > # bool DibSect::CopyWindow(hwnd)
      > # Copy the window rectangle. Equivalent to
      >
      > $ds->CopyClient(GetDesktopWindow(),
      > \@{[GetWindowRect($w)]});
      > </sample>
      >
      > They both allow to specify a RECTANGLE. However, I
      > can't make heads
      > or tails of the syntax of the function implentation.
      >
      > Does anyone know how to accomplish capturing a
      > rectangle from a
      > window getting a smaller image?
      >
      > The solution that I have right now is to capture
      > the WHOLE window
      > and then slice and dice it to get what I want. This
      > is way too slow.
      >
      >
      >
      > Thanks!
      >
      > N
      >
      >
      >
      >
      >
      >
      >
      >
      >
      >
      >
    • Carl Nagle
      [ 3. bool DibSect::CopyClient(hwnd,[rect]) does not have any examples...what the heck is [rect]?? What is the difference between a window and a client? [IF
      Message 2 of 7 , Nov 11, 2004
        [ 3. bool DibSect::CopyClient(hwnd,[rect]) does not have any examples...what the heck is [rect]?? What is the difference between a window and a client? [IF ANYONE CAN ANSWER THIS PLEASE DO] ]

        My semi-experienced 'guess' is that [rect] defines the rectangle area (x1,y1,x2,y2 or some similar structure) within the Window client area to copy. The client or client area is generally considered to be the area inside the borders and below the title bar, menu, and maybe some toolbars where the real meat of the application is displayed in the window -- the client area of the window.

        {:{>
      • Danny R. Faught
        ... I m curious - what was it that you couldn t accomplish without writing C code? With pack and unpack, and the POSIX module, I m able to do a large majority
        Message 3 of 7 , Nov 11, 2004
          > ON CPAN they have a module called "Inline C" that
          > allows a programmer to write "C" functions directly in
          > their PERL scripts and call them, pass refs, etc.

          I'm curious - what was it that you couldn't accomplish without writing C
          code?

          With pack and unpack, and the POSIX module, I'm able to do a large
          majority of the tasks that I can do with C on Unix (granted, pack and
          unpack tend to be hard to grasp). Is it not so easy on Windows?
          --
          Danny R. Faught
          Tejas Software Consulting
          http://tejasconsulting.com/
        • pkaluski
          Hi, Did you try Win32-GUI-DIBitmap? I don t have much experience with this module. I have just done few simple things. But I was under impression that the
          Message 4 of 7 , Nov 11, 2004
            Hi,
            Did you try Win32-GUI-DIBitmap?
            I don't have much experience with this module. I have just done few
            simple things. But I was under impression that the module is simple
            to use and works fine. It operates in Win32::GUI objects but it
            worked fine when I passed it a blessed hash reference with '-handle'
            set to window handle.
            Look under http://perso.club-internet.fr/rocherl/Win32GUI.html

            -Piotr
          • Nicole Sheldon
            Piotr - Thanks!!! You are a lifesaver. Here is my test script: #!/usr/bin/perl -w # filename: testWin32GuiDIBitmap.pl ### Declarations ### use
            Message 5 of 7 , Nov 12, 2004
              Piotr -

              Thanks!!! You are a lifesaver.


              Here is my test script:

              #!/usr/bin/perl -w
              # filename: testWin32GuiDIBitmap.pl


              ### Declarations ###
              use Win32::GUI::DIBitmap;
              use Time::HiRes qw(usleep ualarm gettimeofday
              tv_interval);


              ### Process Profiler ###
              ($seconds1, $microseconds1) = gettimeofday;


              ### Core ###
              $filename="c:\\ocr\\dev\\test.bmp";
              $out="c:\\ocr\\dev\\out.bmp";
              $dib = newFromFile Win32::GUI::DIBitmap ($filename);
              $height=$dib->GetHeight();
              $width=$dib->GetWidth();
              for($h=0;$h<$height;$h++) {
              for($w=0;$w<$width;$w++) {

              $p=$dib->GetPixel($w,$h);
              $hexp = sprintf("%X", $p);
              my $r=reverse((chop $hexp).(chop $hexp));

              $r=255-hex($r); # invert the image to test
              image processing
              $dib->SetPixel($w,$h,$r,$r,$r);
              }
              }

              print "width: $w, height $h\n";
              $dib->SaveToFile($out);


              ### Process Profiler ###
              ($seconds2, $microseconds2) = gettimeofday;
              $eum=$microseconds2-$microseconds1;
              $es=$seconds2-$seconds1;
              $sec=$eum / 1000000;
              print "seconds elapsed: $es, microseconds: $eum ($sec
              of a second)\n";



              I have been looking for this module for a long time
              now. Thank you much for pointing it out to me.


              Regards,

              Nicole


              --- pkaluski <pkaluski@...> wrote:

              >
              > Hi,
              > Did you try Win32-GUI-DIBitmap?
              > I don't have much experience with this module. I
              > have just done few
              > simple things. But I was under impression that the
              > module is simple
              > to use and works fine. It operates in Win32::GUI
              > objects but it
              > worked fine when I passed it a blessed hash
              > reference with '-handle'
              > set to window handle.
              > Look under
              > http://perso.club-internet.fr/rocherl/Win32GUI.html
              >
              > -Piotr
              >
              >
              >
              >
            • snikki326
              I figured out the answer to this and never posted it: # example PERL subroutine sub getBMP { # gets specified section of visible window my
              Message 6 of 7 , Jan 24, 2005
                I figured out the answer to this and never posted it:


                # example PERL subroutine <cut and paste>
                sub getBMP { # gets specified section of visible window
                my $description = shift; # ex: "Yahoo!"
                my $filename = shift; # output filename

                $ds = new Win32::GuiTest::DibSect();
                @array = (0,0,100,100);
                $ref = \@array;
                my @windows = FindWindowLike(0, $description,0);
                for (@windows) {
                SetForegroundWindow($_);
                $ds->CopyClient($_,$ref); #uses a reference to array
                #$ds->CopyWindow($_);
                #$ds->ToGrayScale();
                $file=$filename.".bmp";
                $ds->SaveAs("$file");
                #$ds->ToClipboard();
                }
                }

                it is really quite simple - but maybe not to a beginner.


                N


                --- In perlguitest@yahoogroups.com, Nicole Sheldon <snikki326@y...>
                wrote:
                >
                > Piotr -
                >
                > Thanks!!! You are a lifesaver.
                >
                >
                > Here is my test script:
                >
                > #!/usr/bin/perl -w
                > # filename: testWin32GuiDIBitmap.pl
                >
                >
                > ### Declarations ###
                > use Win32::GUI::DIBitmap;
                > use Time::HiRes qw(usleep ualarm gettimeofday
                > tv_interval);
                >
                >
                > ### Process Profiler ###
                > ($seconds1, $microseconds1) = gettimeofday;
                >
                >
                > ### Core ###
                > $filename="c:\\ocr\\dev\\test.bmp";
                > $out="c:\\ocr\\dev\\out.bmp";
                > $dib = newFromFile Win32::GUI::DIBitmap ($filename);
                > $height=$dib->GetHeight();
                > $width=$dib->GetWidth();
                > for($h=0;$h<$height;$h++) {
                > for($w=0;$w<$width;$w++) {
                >
                > $p=$dib->GetPixel($w,$h);
                > $hexp = sprintf("%X", $p);
                > my $r=reverse((chop $hexp).(chop $hexp));
                >
                > $r=255-hex($r); # invert the image to test
                > image processing
                > $dib->SetPixel($w,$h,$r,$r,$r);
                > }
                > }
                >
                > print "width: $w, height $h\n";
                > $dib->SaveToFile($out);
                >
                >
                > ### Process Profiler ###
                > ($seconds2, $microseconds2) = gettimeofday;
                > $eum=$microseconds2-$microseconds1;
                > $es=$seconds2-$seconds1;
                > $sec=$eum / 1000000;
                > print "seconds elapsed: $es, microseconds: $eum ($sec
                > of a second)\n";
                >
                >
                >
                > I have been looking for this module for a long time
                > now. Thank you much for pointing it out to me.
                >
                >
                > Regards,
                >
                > Nicole
                >
                >
                > --- pkaluski <pkaluski@p...> wrote:
                >
                > >
                > > Hi,
                > > Did you try Win32-GUI-DIBitmap?
                > > I don't have much experience with this module. I
                > > have just done few
                > > simple things. But I was under impression that the
                > > module is simple
                > > to use and works fine. It operates in Win32::GUI
                > > objects but it
                > > worked fine when I passed it a blessed hash
                > > reference with '-handle'
                > > set to window handle.
                > > Look under
                > > http://perso.club-internet.fr/rocherl/Win32GUI.html
                > >
                > > -Piotr
                > >
                > >
                > >
                > >
              Your message has been successfully submitted and would be delivered to recipients shortly.