You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mac Retina屏Java/Kotlin应用如何截取正确分辨率全屏截图?

解决MacBook Pro Retina屏Java Robot截图分辨率问题

这事儿我之前也踩过坑!核心原因是Retina屏的HiDPI缩放机制——Mac系统会用逻辑分辨率(比如你看到的19201200)来适配应用,而Java的Toolkit和Robot类默认只会读取这个逻辑分辨率,不是屏幕真实的物理分辨率(28801800)。硬编码尺寸没用,因为Robot是基于逻辑坐标工作的,超出逻辑范围的区域自然会显示黑框。

下面给你几个可行的解决方案:

1. 通过缩放因子计算物理分辨率

Mac系统会暴露一个缩放因子(Retina屏通常是2.0),你可以通过这个因子把逻辑分辨率转换成物理分辨率:

import java.awt.*;
import java.awt.image.BufferedImage;

public class RetinaScreenshot {
    public static void main(String[] args) throws AWTException {
        // 获取屏幕缩放因子(Retina屏一般是2.0)
        double scaleFactor = Toolkit.getDefaultToolkit().getScreenResolution() / 72.0;
        // 或者直接读取Mac专属系统属性:
        // double scaleFactor = Double.parseDouble(System.getProperty("apple.awt.screenScaleFactor"));

        // 获取逻辑屏幕尺寸
        Dimension logicalSize = Toolkit.getDefaultToolkit().getScreenSize();
        // 计算物理分辨率
        int physicalWidth = (int) (logicalSize.width * scaleFactor);
        int physicalHeight = (int) (logicalSize.height * scaleFactor);

        // 截取对应物理尺寸的全屏截图
        Robot robot = new Robot();
        BufferedImage fullScreenshot = robot.createScreenCapture(new Rectangle(0, 0, physicalWidth, physicalHeight));
        
        // 后续处理截图...
    }
}

2. 用JavaFX获取物理分辨率(更可靠)

如果你的项目允许使用JavaFX,它对HiDPI的支持比AWT更完善,可以直接拿到物理屏幕尺寸:

import java.awt.*;
import java.awt.image.BufferedImage;
import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.stage.Screen;

public class RetinaScreenshotFX {
    public static void main(String[] args) throws AWTException {
        // 初始化JavaFX环境(如果还没初始化的话)
        Application.launch(DummyApp.class);
    }

    public static class DummyApp extends Application {
        @Override
        public void start(javafx.stage.Stage primaryStage) throws AWTException {
            // 获取主屏幕的物理边界
            Screen primaryScreen = Screen.getPrimary();
            Rectangle2D physicalBounds = primaryScreen.getBounds();

            int physicalWidth = (int) physicalBounds.getWidth();
            int physicalHeight = (int) physicalBounds.getHeight();

            // 用Robot截取物理尺寸的截图
            Robot robot = new Robot();
            BufferedImage fullScreenshot = robot.createScreenCapture(new Rectangle(0, 0, physicalWidth, physicalHeight));
            
            // 后续处理...
            primaryStage.close();
        }
    }
}

3. 注意事项

  • Java版本:确保使用Java 8u20及以上版本,早期Java版本对Retina HiDPI的支持很差,容易出现各种分辨率问题。
  • 系统缩放设置:如果你的Mac显示器设置了自定义缩放,缩放因子可能不是2.0,上面的代码依然能自动适配,因为是动态获取的缩放因子。
  • 避免硬编码:不要直接写死28801800,不同Retina屏的物理分辨率可能不同(比如16寸MacBook Pro是30721920),动态计算才是通用方案。

内容的提问来源于stack exchange,提问作者Punika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:53:49