Linux下Java截图遇黑屏问题及跨平台实现方案咨询
问题:Java Robot类截图在Ubuntu下生成全黑图片,Windows正常
代码情况
Windows下正常运行的截图代码:
void linuxShot() throws AWTException, IOException { Robot robot=new Robot(); Dimension d= Toolkit.getDefaultToolkit().getScreenSize(); Rectangle screenRect=new Rectangle(d); BufferedImage bufferedImage=robot.createScreenCapture(screenRect); //save picture File file=new File("temp"+File.separator+"screen.png"); ImageIO.write(bufferedImage,"png",file); }
测试代码:
import javax.imageio.ImageIO; import java.awt.*; import java.io.File; import java.io.IOException; import java.awt.image.BufferedImage; public class Main { public static void main(String[] args) throws AWTException, IOException { Robot robot=new Robot(); Dimension d= Toolkit.getDefaultToolkit().getScreenSize(); Rectangle screenRect=new Rectangle(d); BufferedImage bufferedImage=robot.createScreenCapture(screenRect); //save picture File file=new File("screen.png"); ImageIO.write(bufferedImage,"png",file); } }
系统信息
- JDK版本:
openjdk version "1.8.0_352" OpenJDK Runtime Environment Corretto-8.352.08.1 (build 1.8.0_352-b08) OpenJDK 64-Bit Server VM Corretto-8.352.08.1 (build 25.352-b08, mixed mode)
- 操作系统:
PRETTY_NAME="Ubuntu 22.04.1 LTS" NAME="Ubuntu" VERSION_ID="22.04" VERSION="22.04.1 LTS (Jammy Jellyfish)" VERSION_CODENAME=jammy ID=ubuntu ID_LIKE=debian HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" UBUNTU_CODENAME=jammy
运行问题:Ubuntu下执行代码无异常,但生成的截图为全黑状态,需解决该问题或提供跨平台Java截图方案。
解决方案
修复Robot类全黑截图问题
1. 切换到Xorg显示协议
Ubuntu 22.04默认用Wayland,而Java AWT的Robot类对Wayland支持差,会导致全黑截图:
- 登录界面点击用户名旁的齿轮图标,选择Ubuntu on Xorg后登录,重启再运行代码即可。
2. 赋予Java程序屏幕访问权限(Wayland下)
在Wayland环境中,需要给Java程序授权:
- 先执行命令:
xhost +si:localuser:$USER,再启动Java程序; - 启动时添加参数确保非无头模式:
java -Djava.awt.headless=false Main。
3. 多屏幕场景适配
多显示器环境下,Robot默认可能截取错误区域,可指定具体屏幕设备:
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] screens = ge.getScreenDevices(); // 以第一个屏幕为例,可遍历处理多屏幕 Robot robot = new Robot(screens[0]); Rectangle screenRect = screens[0].getDefaultConfiguration().getBounds(); BufferedImage bufferedImage = robot.createScreenCapture(screenRect);
跨平台替代方案
1. 调用系统原生截图命令(轻量无依赖)
通过调用各系统自带的截图工具,实现跨平台截图:
import java.io.*; import java.nio.file.Files; import java.nio.file.Paths; public class CrossPlatformScreenshot { public static void takeScreenshot(String outputPath) throws IOException, InterruptedException { String os = System.getProperty("os.name").toLowerCase(); Process process; if (os.contains("win")) { // Windows使用PowerShell命令 process = new ProcessBuilder("powershell", "-Command", "(New-Object System.Windows.Forms.ScreenCapture).SaveScreen('" + outputPath + "')").start(); } else if (os.contains("mac")) { // macOS使用screencapture命令 process = new ProcessBuilder("screencapture", "-x", outputPath).start(); } else if (os.contains("nix") || os.contains("nux")) { // Linux使用gnome-screenshot(Ubuntu默认预装) process = new ProcessBuilder("gnome-screenshot", "-f", outputPath).start(); } else { throw new UnsupportedOperationException("不支持当前操作系统"); } process.waitFor(); if (!Files.exists(Paths.get(outputPath))) { throw new IOException("截图生成失败"); } } public static void main(String[] args) throws IOException, InterruptedException { takeScreenshot("cross_platform_screen.png"); } }
2. 使用第三方库(稳定可靠)
推荐用SikuliX,它对跨平台截图支持完善,同时具备图像识别能力:
import org.sikuli.script.Screen; import org.sikuli.script.Image; import java.io.File; public class SikuliScreenshot { public static void main(String[] args) { Screen screen = new Screen(); Image screenshot = screen.capture(); screenshot.save(new File("sikuli_screen.png")); } }
需在项目中添加SikuliX的依赖。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

