我正在开发一个需要捕获屏幕GUI(例如JFrame)图像数据的项目。不知何故,我的应用程序适用于Windows和Mac OS,但对于Linux,它不提供与屏幕GUI相同的图像输出。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.image.BufferedImage;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.io.File;
class jframeExample {
public static BufferedImage getImageData(
Component component) {
BufferedImage image = new BufferedImage(
component.getWidth(),
component.getHeight(),
BufferedImage.TYPE_INT_RGB
);
component.printAll( image.createGraphics() );
return image;
}
public static void main(String[] args){
Runnable r = new Runnable() {
public void run() {
final JFrame f = new JFrame("JFrame Border");
f.setLayout(new BorderLayout());
f.setLocation(500,300);
f.setSize(560, 420);
f.getContentPane().setBackground(Color.BLUE);
JMenuItem screenshot =
new JMenuItem("TakeSnapshot");
screenshot.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent ae) {
BufferedImage imageOutput = getImageData(f);
try {
// write the image as a PNG
ImageIO.write(
imageOutput,
"png",
new File("CapturedImage.png"));
} catch(Exception e) {
e.printStackTrace();
}
}
} );
JMenu menu = new JMenu("Menu");
menu.add(screenshot);
JMenuBar menuBar = new JMenuBar();
menuBar.add(menu);
f.setJMenuBar(menuBar);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
上面的代码将为GUI提供Menu选项,将其捕获为图像输出。您可以将屏幕上的GUI和图像输出视为附加文件。生成的图像与屏幕GUI略有不同。查看JFrame边框的左/右边缘,它与contentPane蓝色重叠。
如何获得与屏幕GUI完全相同的图像或调整左/右边框以使其不与contentPane区域重叠?我使用LookAndFeel类尝试了几个选项,但还没有取得任何成功。任何帮助/建议将不胜感激。
答案 0 :(得分:1)
答案 1 :(得分:0)
尝试更改......
BufferedImage imageOutput = getImageData(f);
到
BufferedImage imageOutput = getImageData(f.getContentPane());
这也可能适用于Linux(我目前无法测试),并且可以轻松解决您的问题。
或者,您可以使用Robot
课程。 Robot
具有更兼容的屏幕捕获功能,但这意味着对您的代码进行了严格的更改。您可以在我的答案的最底部找到代码。让我解释所有变化的原因......
Robot
是执行屏幕截图所需的类。它可以捕获完整的桌面或部分屏幕。在这种情况下,我们将通过在桌面上找到相应的XY坐标来捕获应用程序的蓝色部分。在这种情况下,Robot
需要是静态的,因为您尝试通过main()
方法访问它。因此,Robot
变量必须在main()
方法之外,以便JMenuItem
的{{1}}可以访问它。
ActionListener
new Thread(() -> { /* Do something */ }.start();
。
getLocationOnScreen()
创建屏幕截图,并使用之前的代码保存到文件中。这就是全部!如果您有任何问题,请发表评论,我会稍后再回来查看。
Robot