100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Java Robot 获取高分辨率桌面截图

Java Robot 获取高分辨率桌面截图

时间:2022-03-18 18:00:19

相关推荐

Java Robot 获取高分辨率桌面截图

通过 Robot.createScreenCapture 方法获取屏幕截图(无鼠标)时,发现2160x1440的屏幕,只能生成分辨率为 1440 x 960 的图片。系统是 windows11,缩放为 150%,生成的 1440 x 960 分辨率为 2160/1.5 x 1440/1.5 的值;如果 WIDTH 和 HEIGHT 填写1440 x 960,生成的截图是正常的,知识分辨率小一点,如果填写 2160x1440 ,则生成的截图里,桌面的截图在最终生成的整个图像的左上角,其余部分全部为黑色。

BufferedImage screenCapture = robot.createScreenCapture(new Rectangle(0, 0, WIDTH, HEIGHT)); // 截屏

通过分析 Robot.createScreenCapture 方法发现,其确实适配了缩放的情况,也生成了缩放前后的两个尺寸的图像,但是却返回了低分辨率的那一个。

private synchronized BufferedImage[]createCompatibleImage(Rectangle screenRect, boolean isHiDPI) {checkScreenCaptureAllowed();checkValidRect(screenRect);BufferedImage lowResolutionImage;BufferedImage highResolutionImage;DataBufferInt buffer;WritableRaster raster;BufferedImage[] imageArray;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 delayedToolkit.getDefaultToolkit().sync();GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();gc = SunGraphicsEnvironment.getGraphicsConfigurationAtPoint(gc, screenRect.getCenterX(), screenRect.getCenterY());AffineTransform tx = gc.getDefaultTransform();double uiScaleX = tx.getScaleX();double uiScaleY = tx.getScaleY();int[] pixels;if (uiScaleX == 1 && uiScaleY == 1) {pixels = peer.getRGBPixels(screenRect);buffer = new DataBufferInt(pixels, pixels.length);bandmasks[0] = screenCapCM.getRedMask();bandmasks[1] = screenCapCM.getGreenMask();bandmasks[2] = screenCapCM.getBlueMask();raster = Raster.createPackedRaster(buffer, screenRect.width,screenRect.height, screenRect.width, bandmasks, null);SunWritableRaster.makeTrackable(buffer);highResolutionImage = new BufferedImage(screenCapCM, raster,false, null);imageArray = new BufferedImage[1];imageArray[0] = highResolutionImage;} else {Rectangle scaledRect;if (peer.useAbsoluteCoordinates()) {scaledRect = toDeviceSpaceAbs(gc, screenRect.x,screenRect.y, screenRect.width, screenRect.height);} else {scaledRect = toDeviceSpace(gc, screenRect.x,screenRect.y, screenRect.width, screenRect.height);}// HighResolutionImagepixels = peer.getRGBPixels(scaledRect);buffer = new DataBufferInt(pixels, pixels.length);raster = Raster.createPackedRaster(buffer, scaledRect.width,scaledRect.height, scaledRect.width, bandmasks, null);SunWritableRaster.makeTrackable(buffer);highResolutionImage = new BufferedImage(screenCapCM, raster,false, null);// LowResolutionImagelowResolutionImage = new BufferedImage(screenRect.width,screenRect.height, highResolutionImage.getType());Graphics2D g = lowResolutionImage.createGraphics();g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);g.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);g.drawImage(highResolutionImage, 0, 0,screenRect.width, screenRect.height,0, 0, scaledRect.width, scaledRect.height, null);g.dispose();if(!isHiDPI) {imageArray = new BufferedImage[1];imageArray[0] = lowResolutionImage;//重点看这里} else {imageArray = new BufferedImage[2];imageArray[0] = lowResolutionImage;//重点看这里imageArray[1] = highResolutionImage;//重点看这里}}return imageArray;}

imageArray[0] 是低分辨率的那个图像。

public synchronized BufferedImage createScreenCapture(Rectangle screenRect) {return createCompatibleImage(screenRect, false)[0];}

那么既然高分辨率的生成了,如何获取呢?

public static BufferedImage getHighResolutionImage() throws AWTException {Robot robot = getRobot();MultiResolutionImage multiResolutionImage = robot.createMultiResolutionScreenCapture(new Rectangle(0, 0, WIDTH, HEIGHT));Image image = multiResolutionImage.getResolutionVariant(SCALE_WIDTH, SCALE_HEIGHT);BufferedImage screenCapture = (BufferedImage) image;return screenCapture;}

WIDTH 和 HEIGHT 的值为缩放前的分辨率;在我这个例子里也就是 1440 x 960;

SCALE_WIDTH 和 SCALE_HEIGHT 为缩放后的分辨率;在我这个例子里也就是 2160x1440;

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。