1 package Imager::Screenshot;
3 use vars qw(@ISA $VERSION @EXPORT_OK);
8 @EXPORT_OK = 'screenshot';
15 # try XSLoader first, DynaLoader has annoying baggage
17 XSLoader::load('Imager::Screenshot' => $VERSION);
21 push @ISA, 'DynaLoader';
22 bootstrap Imager::Screenshot $VERSION;
27 # lose the class if called as a method
28 @_ % 2 == 1 and shift;
42 if (defined $opts{hwnd}) {
44 or die "Win32 driver not enabled\n";
45 $result = _win32($opts{hwnd}, $opts{decor}, $opts{left}, $opts{top},
46 $opts{right}, $opts{bottom}, $opts{monitor});
48 elsif (defined $opts{id}) { # X11 window id
49 exists $opts{display} or $opts{display} = 0;
51 or die "X11 driver not enabled\n";
52 $result = _x11($opts{display}, $opts{id}, $opts{left}, $opts{top},
53 $opts{right}, $opts{bottom});
55 elsif (defined $opts{darwin}) { # as long as it's there
57 or die "Darwin driver not enabled\n";
58 $result = _darwin($opts{left}, $opts{top}, $opts{right}, $opts{bottom});
60 elsif ($opts{widget}) {
62 my $top = $opts{widget}->toplevel;
63 my $sys = $top->windowingsystem;
64 if ($sys eq 'win32') {
65 unless (defined &_win32) {
66 Imager->_set_error("Win32 Tk and Win32 support not built");
69 $result = _win32(hex($opts{widget}->id), $opts{decor},
70 $opts{left}, $opts{top}, $opts{right}, $opts{bottom});
72 elsif ($sys eq 'x11') {
73 unless (defined &_x11) {
74 Imager->_set_error("X11 Tk and X11 support not built");
78 my $id_hex = $opts{widget}->id;
80 # is there a way to get the display pointer from Tk?
81 $result = _x11($opts{display}, hex($id_hex), $opts{left}, $opts{top},
82 $opts{right}, $opts{bottom});
85 Imager->_set_error("Unsupported windowing system '$sys'");
91 defined &_win32 ? _win32(0, $opts{decor}, $opts{left}, $opts{top},
92 $opts{right}, $opts{bottom}, $opts{monitor}) :
93 defined &_darwin ? _darwin($opts{left}, $opts{top},
94 $opts{right}, $opts{bottom}) :
95 defined &_x11 ? _x11($opts{display}, 0, $opts{left}, $opts{top},
96 $opts{right}, $opts{bottom}) :
97 die "No drivers enabled\n";
101 Imager->_set_error(Imager->_error_as_msg());
105 # RT #24992 - the Imager typemap entry is broken pre-0.56, so
107 return bless { IMG => $result }, "Imager";
123 my $display = _x11_open(@_);
125 Imager->_set_error(Imager->_error_as_msg);
142 Imager::Screenshot - screenshot to an Imager image
146 use Imager::Screenshot 'screenshot';
149 my $img = screenshot();
152 my $img2 = screenshot(hwnd => $hwnd);
155 my $img3 = screenshot(display => $display, id => $window_id);
158 my $display = Imager::Screenshot::x11_open();
159 Imager::Screenshot::x11_close($display);
161 # test for win32 support
162 if (Imager::Screenshot->have_win32) { ... }
164 # test for x11 support
165 if (Imager::Screenshot->have_x11) { ... }
167 # test for Darwin (Mac OS X) support
168 if (Imager::Screenshot->have_darwin) { ... }
173 Imager::Screenshot captures either a desktop or a specified window and
174 returns the result as an Imager image.
176 Currently the image is always returned as a 24-bit image.
180 =item screenshot hwnd => I<window handle>
182 =item screenshot hwnd => I<window handle>, decor => <capture decorations>
184 =item screenshot hwnd => "active"
186 Retrieve a screenshot under Win32, if I<window handle> is zero,
189 By default, window decorations are not captured, if the C<decor>
190 parameter is set to true then window decorations are included.
192 As of 0.010 hwnd can also be C<"active"> to capture the active (or
193 "foreground") window.
195 =item screenshot hwnd => 0
197 Retrieve a screeshot of the default desktop under Win32.
199 =item screenshot hwnd => 0, monitor => -1
201 Retrieve a screenshot of all attached monitors under Win32.
203 Note: this returns an image with an alpha channel, since there can be
204 regions in the bounding rectangle of all monitors that no particular
207 =item screenshot hwnd => 0, monitor => I<index>
209 Retrieve a screenshot from a particular monitor under Win32. A
210 I<monitor> of zero is always treated as the primary monitor.
212 If the given monitor is not active screenshot() will fail.
214 =item screenshot id => I<window id>
216 =item screenshot id => I<window id>, display => I<display object>
218 Retrieve a screenshot under X11, if I<id> is zero, capture the root
219 window. I<display object> is a integer version of an X11 C< Display *
220 >, if this isn't supplied C<screenshot()> will attempt connect to the
221 the display specified by $ENV{DISPLAY}.
223 Note: taking a screenshot of a remote display is slow.
225 =item screenshot darwin => 0
227 Retrieve a screenshot under Mac OS X. The only supported value for
228 the C<darwin> parameter is C<0>.
230 For a screen capture to be taken, the current user using
231 Imager:Screenshot must be the currently logged in user on the display.
233 If you're using fast user switching, the current user must be the
236 Note: this means you can ssh into a Mac OS X box and screenshot from
237 the ssh session, if you're the current user on the display.
239 =item screenshot widget => I<widget>
241 =item screenshot widget => I<widget>, display => I<display>
243 =item screenshot widget => I<widget>, decor => I<capture decorations>
245 Retrieve a screenshot of a Tk widget, under Win32 or X11, depending on
246 how Tk has been built.
248 If Tk was built for X11 then the display parameter applies.
250 If Tk was built for Win32 then the decor parameter applies.
254 If no C<id>, C<hwnd> or C<widget> parameter is supplied:
260 if Win32 support is compiled, return screenshot(hwnd => 0).
264 if Darwin support is compiled, return screenshot(darwin => 0).
268 if X11 support is compiled, return screenshot(id => 0).
276 You can also supply the following parameters to retrieve a subset of
299 If left or top is negative, then treat that as from the right/bottom
302 If right ot bottom is zero or negative then treat as from the
303 right/bottom edge of the window.
305 So setting all 4 values to 0 retrieves the whole window.
307 # a 10-pixel wide right edge of the window
308 my $right_10 = screenshot(left => -10, ...);
310 # the top-left 100x100 portion of the window
311 my $topleft_100 = screenshot(right => 100, bottom => 100, ...);
313 # 10x10 pixel at the bottom right corner
314 my $bott_right_10 = screenshot(left => -10, top => -10, ...);
316 If screenshot() fails, it will return nothing, and the cause of the
317 failure can be retrieved via Imager->errstr, so typical use could be:
319 my $img = screenshot(...) or die Imager->errstr;
323 Returns true if Win32 support is available.
327 Returns true if X11 support is available.
331 Returns true if Darwin support is available.
333 =item Imager::Screenshot::x11_open
335 =item Imager::Screenshot::x11_open I<display name>
337 Attempts to open a connection to either the display name in
338 $ENV{DISPLAY} or the supplied display name. Returns a value suitable
339 for the I<display> parameter of screenshot, or undef.
341 =item Imager::Screenshot::x11_close I<display>
343 Closes a display returned by Imager::Screenshot::x11_open().
349 screenshot() sets a number of tags in the images it returns, these are:
355 ss_left - the distance between the left side of the window and the
356 left side of the captured area. The same value as the I<left>
357 parameter when that is positive.
361 ss_top - the distance between the top side of the window the top side
362 of the captured area. The same value at the I<top> parameter when
367 ss_window_width - the full width of the window.
371 ss_window_height - the full height of the window.
375 ss_type - the type of capture done, either "Win32" or "X11".
379 To cheaply get the window size you can capture a single pixel:
381 my $im = screenshot(right => 1, bottom => 1);
382 my $window_width = $im->tags(name => 'ss_window_width');
383 my $window_height = $im->tags(name => 'ss_window_height');
387 It's possible to have more than one grab driver available, for
388 example, Win32 and X11, and which is used can have an effect on the
391 Under Win32 or OS X, if there's a screesaver running, then you grab
392 the results of the screensaver.
394 On OS X, you can grab the display from an ssh session as long as the
395 ssh session is under the same user as the currently active user on the
398 Grabbing the root window on a rootless server (eg. Cygwin/X) may not
399 grab the background that you see. In fact, when I tested under
400 Cygwin/X I got the xterm window contents even when the Windows
401 screensaver was running. The root window captured appeared to be that
402 generated by my window manager.
404 Grabbing a window with other windows overlaying it will capture the
405 content of those windows where they hide the window you want to
406 capture. You may want to raise the window to top. This may be a
407 security concern if the overlapping windows contain any sensitive
408 information - true for any screen capture.
412 Imager::Screenshot is licensed under the same terms as Perl itself.
416 Future plans include:
422 window name searches - currently screenshot() requires a window
423 identifier of some sort, it would be more usable if we could supply
424 some other identifier, either a window title or a window class name.
430 Tony Cook <tonyc@cpan.org>