< prev index next >

src/java.desktop/share/classes/java/awt/Robot.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -25,10 +25,11 @@
 
 package java.awt;
 
 import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
+import java.awt.geom.AffineTransform;
 import java.awt.image.BufferedImage;
 import java.awt.image.DataBufferInt;
 import java.awt.image.DirectColorModel;
 import java.awt.image.Raster;
 import java.awt.image.WritableRaster;

@@ -392,10 +393,54 @@
     public synchronized Color getPixelColor(int x, int y) {
         Color color = new Color(peer.getRGBPixel(x, y));
         return color;
     }
 
+    private static int interp(int pixels[], int x, int y, int w, int h, int fractx1, int fracty1) {
+        int fractx0 = 256 - fractx1;
+        int fracty0 = 256 - fracty1;
+        int i = y * w + x;
+        int rgb00 = (x < 0 || y < 0 || x >= w || y >= h) ? 0 : pixels[i];
+        if (fracty1 == 0) {
+            // No interplation with pixels[y+1]
+            if (fractx1 == 0) {
+                // No interpolation with any neighbors
+                return rgb00;
+            }
+            int rgb10 = (y < 0 || x + 1 >= w || y >= h) ? 0 : pixels[i + 1];
+            return interp(rgb00, rgb10, fractx0, fractx1);
+        } else if (fractx1 == 0) {
+            // No interpolation with pixels[x+1]
+            int rgb01 = (x < 0 || x >= w || y + 1 >= h) ? 0 : pixels[i + w];
+            return interp(rgb00, rgb01, fracty0, fracty1);
+        } else {
+            // All 4 neighbors must be interpolated
+            int rgb10 = (y < 0 || x + 1 >= w || y >= h) ? 0 : pixels[i + 1];
+            int rgb01 = (x < 0 || x >= w || y + 1 >= h) ? 0 : pixels[i + w];
+            int rgb11 = (x + 1 >= w || y + 1 >= h) ? 0 : pixels[i + w + 1];
+            return interp(interp(rgb00, rgb10, fractx0, fractx1),
+                    interp(rgb01, rgb11, fractx0, fractx1),
+                    fracty0, fracty1);
+        }
+    }
+
+    private static int interp(int rgb0, int rgb1, int fract0, int fract1) {
+        int a0 = (rgb0 >> 24) & 0xff;
+        int r0 = (rgb0 >> 16) & 0xff;
+        int g0 = (rgb0 >> 8) & 0xff;
+        int b0 = (rgb0) & 0xff;
+        int a1 = (rgb1 >> 24) & 0xff;
+        int r1 = (rgb1 >> 16) & 0xff;
+        int g1 = (rgb1 >> 8) & 0xff;
+        int b1 = (rgb1) & 0xff;
+        int a = (a0 * fract0 + a1 * fract1) >> 8;
+        int r = (r0 * fract0 + r1 * fract1) >> 8;
+        int g = (g0 * fract0 + g1 * fract1) >> 8;
+        int b = (b0 * fract0 + b1 * fract1) >> 8;
+        return (a << 24) | (r << 16) | (g << 8) | b;
+    }
+
     /**
      * Creates an image containing pixels read from the screen.  This image does
      * not include the mouse cursor.
      * @param   screenRect      Rect to capture in screen coordinates
      * @return  The captured image

@@ -403,10 +448,26 @@
      * @throws  SecurityException if {@code readDisplayPixels} permission is not granted
      * @see     SecurityManager#checkPermission
      * @see     AWTPermission
      */
     public synchronized BufferedImage createScreenCapture(Rectangle screenRect) {
+          return createScreenCapture(screenRect, false);
+    }
+
+    /**
+     * Creates an image containing pixels read from the screen.  This image does
+     * not include the mouse cursor.
+     * @param   screenRect  Rect to capture in screen coordinates
+     * @param   isHiDPI Specifies if HiDPI
+     * @return  The captured image
+     * @throws  IllegalArgumentException if {@code screenRect} width and height are not greater than zero
+     * @throws  SecurityException if {@code readDisplayPixels} permission is not granted
+     * @see     SecurityManager#checkPermission
+     * @see     AWTPermission
+     */
+    public synchronized BufferedImage createScreenCapture(Rectangle screenRect, 
+            boolean isHiDPI) {
         checkScreenCaptureAllowed();
 
         checkValidRect(screenRect);
 
         BufferedImage image;

@@ -427,15 +488,61 @@
         }
 
         // need to sync the toolkit prior to grabbing the pixels since in some
         // cases rendering to the screen may be delayed
         Toolkit.getDefaultToolkit().sync();
-
+        AffineTransform tx = GraphicsEnvironment.
+                getLocalGraphicsEnvironment().getDefaultScreenDevice().
+                getDefaultConfiguration().getDefaultTransform();
+        double uiScaleX = tx.getScaleX();
+        double uiScaleY = tx.getScaleY();
         int pixels[];
         int[] bandmasks = new int[3];
 
+        if (uiScaleX == 1 && uiScaleY == 1) {
         pixels = peer.getRGBPixels(screenRect);
+        } else {
+            int x = screenRect.x;
+            int y = screenRect.y;
+            int width = screenRect.width;
+            int height = screenRect.height;
+            int pminx = (int) Math.floor(x * uiScaleX);
+            int pminy = (int) Math.floor(y * uiScaleY);
+            int pmaxx = (int) Math.ceil((x + width) * uiScaleX);
+            int pmaxy = (int) Math.ceil((y + height) * uiScaleY);
+            int pwidth = pmaxx - pminx;
+            int pheight = pmaxy - pminy;
+            int temppixels[];
+            Rectangle rect = new Rectangle(pminx, pminy, pwidth, pheight);
+            temppixels = peer.getRGBPixels(rect);
+            if (isHiDPI) {
+                pixels = temppixels;
+                screenRect.width = pwidth;
+                screenRect.height = pheight;
+            } else {
+                pixels = new int[width * height];
+                int index = 0;
+                for (int iy = 0; iy < height; iy++) {
+                    float rely = (float) (((y + iy + 0.5f) * uiScaleY)
+                            - (pminy + 0.5f));
+                    int irely = (int) Math.floor(rely);
+                    int fracty = (int) ((rely - irely) * 256);
+                    for (int ix = 0; ix < width; ix++) {
+                        float relx = (float) (((x + ix + 0.5f) * uiScaleX)
+                                - (pminx + 0.5f));
+                        int irelx = (int) Math.floor(relx);
+                        int fractx = (int) ((relx - irelx) * 256);
+                        pixels[index++]
+                                = interp(temppixels, irelx, irely, pwidth,
+                                        pheight, fractx, fracty);
+                    }
+                }
+                screenRect.width = width;
+                screenRect.height = height;
+            }
+        }
+
         buffer = new DataBufferInt(pixels, pixels.length);
 
         bandmasks[0] = screenCapCM.getRedMask();
         bandmasks[1] = screenCapCM.getGreenMask();
         bandmasks[2] = screenCapCM.getBlueMask();
< prev index next >