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
相关产品推荐
相关产品推荐

