1 /*
2 * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.awt;
27
28 import java.awt.event.InputEvent;
29 import java.awt.event.KeyEvent;
30 import java.awt.image.BufferedImage;
31 import java.awt.image.DataBufferInt;
32 import java.awt.image.DirectColorModel;
33 import java.awt.image.Raster;
34 import java.awt.image.WritableRaster;
35 import java.awt.peer.RobotPeer;
36
37 import sun.awt.AWTPermissions;
38 import sun.awt.ComponentFactory;
39 import sun.awt.SunToolkit;
40 import sun.awt.image.SunWritableRaster;
41
42 /**
43 * This class is used to generate native system input events
44 * for the purposes of test automation, self-running demos, and
45 * other applications where control of the mouse and keyboard
46 * is needed. The primary purpose of Robot is to facilitate
47 * automated testing of Java platform implementations.
48 * <p>
49 * Using the class to generate input events differs from posting
388 * @param x X position of pixel
389 * @param y Y position of pixel
390 * @return Color of the pixel
391 */
392 public synchronized Color getPixelColor(int x, int y) {
393 Color color = new Color(peer.getRGBPixel(x, y));
394 return color;
395 }
396
397 /**
398 * Creates an image containing pixels read from the screen. This image does
399 * not include the mouse cursor.
400 * @param screenRect Rect to capture in screen coordinates
401 * @return The captured image
402 * @throws IllegalArgumentException if {@code screenRect} width and height are not greater than zero
403 * @throws SecurityException if {@code readDisplayPixels} permission is not granted
404 * @see SecurityManager#checkPermission
405 * @see AWTPermission
406 */
407 public synchronized BufferedImage createScreenCapture(Rectangle screenRect) {
408 checkScreenCaptureAllowed();
409
410 checkValidRect(screenRect);
411
412 BufferedImage image;
413 DataBufferInt buffer;
414 WritableRaster raster;
415
416 if (screenCapCM == null) {
417 /*
418 * Fix for 4285201
419 * Create a DirectColorModel equivalent to the default RGB ColorModel,
420 * except with no Alpha component.
421 */
422
423 screenCapCM = new DirectColorModel(24,
424 /* red mask */ 0x00FF0000,
425 /* green mask */ 0x0000FF00,
426 /* blue mask */ 0x000000FF);
427 }
428
429 // need to sync the toolkit prior to grabbing the pixels since in some
430 // cases rendering to the screen may be delayed
431 Toolkit.getDefaultToolkit().sync();
432
433 int pixels[];
434 int[] bandmasks = new int[3];
435
436 pixels = peer.getRGBPixels(screenRect);
437 buffer = new DataBufferInt(pixels, pixels.length);
438
439 bandmasks[0] = screenCapCM.getRedMask();
440 bandmasks[1] = screenCapCM.getGreenMask();
441 bandmasks[2] = screenCapCM.getBlueMask();
442
443 raster = Raster.createPackedRaster(buffer, screenRect.width, screenRect.height, screenRect.width, bandmasks, null);
444 SunWritableRaster.makeTrackable(buffer);
445
446 image = new BufferedImage(screenCapCM, raster, false, null);
447
448 return image;
449 }
450
451 private static void checkValidRect(Rectangle rect) {
452 if (rect.width <= 0 || rect.height <= 0) {
453 throw new IllegalArgumentException("Rectangle width and height must be > 0");
454 }
455 }
456
457 private static void checkScreenCaptureAllowed() {
458 SecurityManager security = System.getSecurityManager();
459 if (security != null) {
460 security.checkPermission(AWTPermissions.READ_DISPLAY_PIXELS_PERMISSION);
461 }
462 }
463
464 /*
465 * Called after an event is generated
466 */
467 private void afterEvent() {
468 autoWaitForIdle();
|
1 /*
2 * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.awt;
27
28 import java.awt.event.InputEvent;
29 import java.awt.event.KeyEvent;
30 import java.awt.geom.AffineTransform;
31 import java.awt.image.BaseMultiResolutionImage;
32 import java.awt.image.BufferedImage;
33 import java.awt.image.DataBufferInt;
34 import java.awt.image.DirectColorModel;
35 import java.awt.image.Raster;
36 import java.awt.image.WritableRaster;
37 import java.awt.peer.RobotPeer;
38
39 import sun.awt.AWTPermissions;
40 import sun.awt.ComponentFactory;
41 import sun.awt.SunToolkit;
42 import sun.awt.image.SunWritableRaster;
43
44 /**
45 * This class is used to generate native system input events
46 * for the purposes of test automation, self-running demos, and
47 * other applications where control of the mouse and keyboard
48 * is needed. The primary purpose of Robot is to facilitate
49 * automated testing of Java platform implementations.
50 * <p>
51 * Using the class to generate input events differs from posting
390 * @param x X position of pixel
391 * @param y Y position of pixel
392 * @return Color of the pixel
393 */
394 public synchronized Color getPixelColor(int x, int y) {
395 Color color = new Color(peer.getRGBPixel(x, y));
396 return color;
397 }
398
399 /**
400 * Creates an image containing pixels read from the screen. This image does
401 * not include the mouse cursor.
402 * @param screenRect Rect to capture in screen coordinates
403 * @return The captured image
404 * @throws IllegalArgumentException if {@code screenRect} width and height are not greater than zero
405 * @throws SecurityException if {@code readDisplayPixels} permission is not granted
406 * @see SecurityManager#checkPermission
407 * @see AWTPermission
408 */
409 public synchronized BufferedImage createScreenCapture(Rectangle screenRect) {
410 return (BufferedImage) createScreenCapture(screenRect, false);
411 }
412
413 /**
414 * Creates an image containing pixels read from the screen.
415 * This image does not include the mouse cursor.
416 * Returns BufferedImage for Non-HiDPI display and
417 * MultiResolutionImage for HiDPI display with two resolution variants,
418 * Base Image with user specified size and
419 * High Resolution Image with original size.
420 * @param screenRect Rect to capture in screen coordinates
421 * @param isHiDPI Indicates if HiDPI Display
422 * @return The captured image
423 * @throws IllegalArgumentException if {@code screenRect} width and height are not greater than zero
424 * @throws SecurityException if {@code readDisplayPixels} permission is not granted
425 * @see SecurityManager#checkPermission
426 * @see AWTPermission
427 */
428
429 public synchronized Image createScreenCapture(Rectangle screenRect, boolean isHiDPI) {
430 checkScreenCaptureAllowed();
431
432 checkValidRect(screenRect);
433
434 BufferedImage lowResolutionImage;
435 BufferedImage highResolutionImage;
436 DataBufferInt buffer;
437 WritableRaster raster;
438
439 if (screenCapCM == null) {
440 /*
441 * Fix for 4285201
442 * Create a DirectColorModel equivalent to the default RGB ColorModel,
443 * except with no Alpha component.
444 */
445
446 screenCapCM = new DirectColorModel(24,
447 /* red mask */ 0x00FF0000,
448 /* green mask */ 0x0000FF00,
449 /* blue mask */ 0x000000FF);
450 }
451
452 int[] bandmasks = new int[3];
453 bandmasks[0] = screenCapCM.getRedMask();
454 bandmasks[1] = screenCapCM.getGreenMask();
455 bandmasks[2] = screenCapCM.getBlueMask();
456
457 // need to sync the toolkit prior to grabbing the pixels since in some
458 // cases rendering to the screen may be delayed
459 Toolkit.getDefaultToolkit().sync();
460 AffineTransform tx = GraphicsEnvironment.
461 getLocalGraphicsEnvironment().getDefaultScreenDevice().
462 getDefaultConfiguration().getDefaultTransform();
463 double uiScaleX = tx.getScaleX();
464 double uiScaleY = tx.getScaleY();
465 int pixels[];
466
467 if (uiScaleX == 1 && uiScaleY == 1) {
468 pixels = peer.getRGBPixels(screenRect);
469 buffer = new DataBufferInt(pixels, pixels.length);
470
471 bandmasks[0] = screenCapCM.getRedMask();
472 bandmasks[1] = screenCapCM.getGreenMask();
473 bandmasks[2] = screenCapCM.getBlueMask();
474
475 raster = Raster.createPackedRaster(buffer, screenRect.width,
476 screenRect.height, screenRect.width, bandmasks, null);
477 SunWritableRaster.makeTrackable(buffer);
478
479 return new BufferedImage(screenCapCM, raster, false, null);
480
481 } else {
482
483 int x = screenRect.x;
484 int y = screenRect.y;
485 int width = screenRect.width;
486 int height = screenRect.height;
487 int pminx = (int) Math.floor(x * uiScaleX);
488 int pminy = (int) Math.floor(y * uiScaleY);
489 int pmaxx = (int) Math.ceil((x + width) * uiScaleX);
490 int pmaxy = (int) Math.ceil((y + height) * uiScaleY);
491 int pwidth = pmaxx - pminx;
492 int pheight = pmaxy - pminy;
493 int temppixels[];
494 Rectangle scaledRect = new Rectangle(pminx, pminy, pwidth, pheight);
495 temppixels = peer.getRGBPixels(scaledRect);
496
497 // HighResolutionImage
498 pixels = temppixels;
499 buffer = new DataBufferInt(pixels, pixels.length);
500 raster = Raster.createPackedRaster(buffer, scaledRect.width,
501 scaledRect.height, scaledRect.width, bandmasks, null);
502 SunWritableRaster.makeTrackable(buffer);
503
504 highResolutionImage = new BufferedImage(screenCapCM, raster,
505 false, null);
506
507 // LowResolutionImage
508 lowResolutionImage = new BufferedImage(screenRect.width,
509 screenRect.height, highResolutionImage.getType());
510 Graphics2D g = lowResolutionImage.createGraphics();
511 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
512 RenderingHints.VALUE_INTERPOLATION_BILINEAR);
513 g.setRenderingHint(RenderingHints.KEY_RENDERING,
514 RenderingHints.VALUE_RENDER_QUALITY);
515 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
516 RenderingHints.VALUE_ANTIALIAS_ON);
517 g.drawImage(highResolutionImage, screenRect.x, screenRect.y,
518 screenRect.width, screenRect.height,
519 scaledRect.x, scaledRect.y,
520 scaledRect.width, scaledRect.height, null);
521 g.dispose();
522
523 if (!isHiDPI) {
524 return lowResolutionImage;
525 } else {
526 // MultiResoltuionImage
527 return new BaseMultiResolutionImage(
528 lowResolutionImage, highResolutionImage);
529 }
530 }
531 }
532
533 private static void checkValidRect(Rectangle rect) {
534 if (rect.width <= 0 || rect.height <= 0) {
535 throw new IllegalArgumentException("Rectangle width and height must be > 0");
536 }
537 }
538
539 private static void checkScreenCaptureAllowed() {
540 SecurityManager security = System.getSecurityManager();
541 if (security != null) {
542 security.checkPermission(AWTPermissions.READ_DISPLAY_PIXELS_PERMISSION);
543 }
544 }
545
546 /*
547 * Called after an event is generated
548 */
549 private void afterEvent() {
550 autoWaitForIdle();
|