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

How to get slice of window instead of whole thing? DibSect

Expand Messages
  • snikki326
    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
    Message 1 of 7 , Nov 8, 2004
    • 0 Attachment
      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
    • 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 2 of 7 , Nov 11, 2004
      • 0 Attachment
        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 3 of 7 , Nov 11, 2004
        • 0 Attachment
          [ 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 4 of 7 , Nov 11, 2004
          • 0 Attachment
            > 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 5 of 7 , Nov 11, 2004
            • 0 Attachment
              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 6 of 7 , Nov 12, 2004
              • 0 Attachment
                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 7 of 7 , Jan 24, 2005
                • 0 Attachment
                  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.