Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
Goal: How to quickly locate/find a graphic on the screen...
using Win32::GuiTest to load data into Jinitiator application on Windows 2000 desktop.
Challenge: determine when data is accepted, or error occurred.
ie: grab the error box and compare with known image(s)..
Grabbing the screen is easy, (alt-PrintScreen), grab clipboard image...
PerlMagick can access it fast as a blob image.
scanning the whole image ( 1024 x 768 ) for a match
in Perl can take more than 30 seconds...
Graphical searching appears to not be an available function
in PerMagick nor GD module...
Any ideas for a speedup using Perl ?
Re: GUI Automation - locate image
by Corion (Patriarch) on Mar 08, 2004 at 21:14 UTC
|
Depending on how your target application displays its windows, you can possibly dig down through it to get at the real text and caption of the window instead of needing to capture screens.
Take a look at the included minispy.pl program and especially the FindWindow() routine - you will need a bit of knowledge about GDI or generally windowing APIs though, to make sense of the data returned by it.
Otherwise, if you have to stay on the graphic route, consider using PDL - I think PodMaster has a PPM package for Win32.
| [reply] |
Re: GUI Automation - locate image
by paulbort (Hermit) on Mar 09, 2004 at 03:56 UTC
|
| [reply] |
|
I'm at work now, where I use Win32::GUITest to automate a stubborn application, and here is a modified version of the spy-- program that I used to look at the current selection in a listbox. The stubborn program displays its status by filling a listbox with all possible status values and then selecting the active status...
# $Id: guitest-spy.html,v 1.1 2001/09/19 23:31:36 erngui Exp $
#
# MS has a very nice tool (Spy++).
# This is Spy--
#
use Win32::GuiTest qw/FindWindowLike GetWindowText GetClassName IsWind
+owEnabled GetWindowID
GetChildDepth GetDesktopWindow GetComboContents GetListContents Ge
+tListText SendKeys /;
use Win32::API;
for (FindWindowLike(0,qr/^Explorer -/)) {
SendKeys("%ao");
print "Looking for dialog\n";
my @dialog = FindWindowLike($_,qr/Optionen/,"");
print "Looking for listbox\n";
my @listbox = FindWindowLike($dialog[0],"","",752);
while (1) {
print "Getting current selection\n";
my $i = SendMessage($listbox[0], LB_GETCURRSEL,0,0 );
print $i;
print "Getting current selection text\n";
my $t = GetListText($listbox[0],$i);
print $t,"\n";
sleep 1;
};
}
| [reply] [d/l] |
|
| [reply] |
|
Thanks, but Application is running within a windows frame utilizing some Java SunAwtCanvas... anything within it is not visible to me from Perl. only graphically.
Found the Win32::ActAcc module, here is the Perl code I used to detect any "lasting change" over a 2 second period...
It appears very handy for working with other applications...
use Strict;
use Win32::OLE;
use Win32::ActAcc;
use Win32::GuiTest qw(:ALL :SW);
my @win;
my %Wnm;
my %VW;
Win32::OLE->Initialize();
while ( 1 ) {
@win = ();
@win = FindWindowLike();
#*# report any "lost" windows:
for $win ( @win ) { delete $Wnm{$win}; }
if ( scalar keys %Wnm) {
print "Lost:\n";
my @Lost = sort keys %Wnm;
for (@Lost) { print "$Wnm{$_}\n"; delete $Wnm{$_}; }
print "\n";
}
for $win ( @win ) { dumpwin($win); }
print "\n----\n";
sleep(2);
}
exit;
sub dumpwin {
my $win = shift;
print "Null handle\n", return unless ($win);
my $w_text = $win . ' ' . GetWindowText($win);
$w_text .= " class=" . GetClassName($win);
my $w_state = ' V=' . IsWindowVisible($win) . ' E=';
$w_state .= IsWindowEnabled($win);
$Wnm{$win} = $w_text . ' ' . $w_state;
my $ao = Win32::ActAcc::AccessibleObjectFromWindow($win);
my $aatxt = '';
$aatxt = $ao->describe() if defined $ao;
$w_state .= ' ' . $aatxt;
if ( exists $VW{$win} ) {
return if ( $VW{$win} eq $w_state );
}
$VW{$win} = $w_state;
print $win, GetWindowText($win);
print " class=", GetClassName($win);
print " vis=", IsWindowVisible($win);
print " en=", IsWindowEnabled($win);
print "\n ",$aatxt, "\n";
}
| [reply] [d/l] |
Re: GUI Automation - locate image
by bageler (Hermit) on Mar 08, 2004 at 21:15 UTC
|
after google search, I found this tidbit:
This problem is called "image registration" or "image stitching" or "image
mosaicing". There are plently of papers written on the subject, most of
which don't use AI techniques. The most widely used method is getting the
Fourier transform of both images and comparing them; but this only works if
there is no change in rotation between the images. I, personally, have
written a paper to do just that using Zernike moments. Many other approaches
exist, each with it's ups and downs.
| [reply] |
Re: GUI Automation - locate image
by Juerd (Abbot) on Mar 08, 2004 at 21:23 UTC
|
One ugly and fun way would be to use the regex engine. 1024*786 is less than 1 MB so it could be fast even. (Assuming 8 bpp)
Just insert .{ screen dump width - expected image width } after every expected image width characters (but not at the end).
| [reply] |
Re: GUI Automation - locate image
by halley (Prior) on Mar 09, 2004 at 15:16 UTC
|
Image searching is a great automated testing method for verifying that DRAWING code is working correctly. It's not a good method for pretty much anything else in the GUI space.
For real image searching, there are a lot of interesting tests. Juerd mentioned using the regex engine, which has its merits. There are other sparse comparisons which help find exact pixel matches of various swatches. Another poster mentioned image mosaicing methods like least squared errors, but those are better for situations where the alignment, rotation, scale, coloring of two images are not identical.
Otherwise, please please please dig through the window manager to verify text strings, not pixels. Any change in the test user's Appearance preferences, or operating system version, or even a different video driver, would totally blow all your tests.
-- [ e d @ h a l l e y . c c ]
| [reply] |
Re: GUI Automation - locate image
by zakzebrowski (Curate) on Mar 09, 2004 at 21:05 UTC
|
Not sure if it will help, but look at the Win32::Clipboard module to progromatically do the clipboard capture of the image... good luck.
| [reply] |
|
|