< prev index next >
src/java.desktop/share/classes/java/awt/Robot.java
Print this page
@@ -25,10 +25,12 @@
package java.awt;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BaseMultiResolutionImage;
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 +394,171 @@
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.
+ * Returns BufferedImage for Non-HiDPI display and MultiResolutionImage
+ * for HiDPI display with two resolution variants.
+ * @param screenRect Rect to capture in screen coordinates
+ * @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 Image createHiDPIScreenCapture(Rectangle screenRect) {
+ checkScreenCaptureAllowed();
+
+ checkValidRect(screenRect);
+
+ BufferedImage lowResolutionImage;
+ BufferedImage highResolutionImage;
+ DataBufferInt buffer;
+ WritableRaster raster;
+
+ if (screenCapCM == null) {
+ /*
+ * Fix for 4285201
+ * Create a DirectColorModel equivalent to the default RGB ColorModel,
+ * except with no Alpha component.
+ */
+
+ screenCapCM = new DirectColorModel(24,
+ /* red mask */ 0x00FF0000,
+ /* green mask */ 0x0000FF00,
+ /* blue mask */ 0x000000FF);
+ }
+
+ int[] bandmasks = new int[3];
+ bandmasks[0] = screenCapCM.getRedMask();
+ bandmasks[1] = screenCapCM.getGreenMask();
+ bandmasks[2] = screenCapCM.getBlueMask();
+
+ // 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[];
+
+ // Return normal screenCapture for Non-HiDPI Display
+ if(uiScaleX ==1 && uiScaleY==1){
+ return createScreenCapture(screenRect);
+ }
+
+ 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);
+
+ // HighResolutionImage
+ pixels = temppixels;
+ screenRect = rect;
+
+ buffer = new DataBufferInt(pixels, pixels.length);
+ raster = Raster.createPackedRaster(buffer, screenRect.width,
+ screenRect.height, screenRect.width, bandmasks, null);
+ SunWritableRaster.makeTrackable(buffer);
+
+ highResolutionImage = new BufferedImage(screenCapCM, raster, false, null);
+
+ // LowResolutionImage
+ 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);
+ raster = Raster.createPackedRaster(buffer, screenRect.width,
+ screenRect.height, screenRect.width, bandmasks, null);
+ SunWritableRaster.makeTrackable(buffer);
+
+ lowResolutionImage = new BufferedImage(screenCapCM, raster, false, null);
+
+ // MultiResoltuionImage
+ BaseMultiResolutionImage image = new BaseMultiResolutionImage(
+ lowResolutionImage,highResolutionImage);
+
+ return image;
+ }
+
/**
* 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
< prev index next >