< 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 >