我正在做一个项目,需要捕获屏幕图形用户界面的图像数据(例如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提供菜单选项,以将其捕获为图像输出。您可以看到屏幕上的图形用户界面和它的图像输出,因为附加的files.Generated图像与屏幕上的图形用户界面略有不同。查看JFrame边框的左/右边缘,它与contentPane的蓝色重叠。
如何获得与屏幕上的图形用户界面完全相同的图像,或者调整左右边框,使其不与contentPane区域重叠?我使用LookAndFeel类尝试了几个选项,但仍未获得任何成功。如有任何帮助/建议,我们将不胜感激。
On-Screen GUI
CapturedImage
发布于 2016-08-10 05:00:30
发布于 2016-08-11 05:53:06
快速解决方案
尝试更改...
BufferedImage imageOutput = getImageData(f);
至
BufferedImage imageOutput = getImageData(f.getContentPane());
这可能也可以在Linux上工作(我现在不能测试它),并且可以很容易地解决你的问题。
解决方案
或者,您可以使用Robot
类。Robot
具有更兼容的屏幕捕获功能,但这意味着要对您的代码进行严重更改。你可以在我的答案的最下面找到代码。让我解释一下所有这些变化的原因。
Robot
是执行屏幕捕获所需的类。它可以捕获整个桌面,也可以捕获部分屏幕。在本例中,我们将通过找出桌面上各自的XY坐标,让它捕获应用程序的蓝色部分。在这种情况下,Robot
需要是静态的,因为您试图通过main()
方法访问它。因此,Robot
变量需要在main()
方法的外部,以便JMenuItem
的ActionListener
可以访问它。new Thread(() -> { /* Do something */ }.start();
getLocationOnScreen()
。Robot
创建,并使用之前的代码保存到文件中。就这样!如果你有任何问题,请发表评论,我稍后会再来查看。
代码
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
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;
}
static Robot robot = null;
public static void main(String[] args){
Runnable r = new Runnable() {
public void run() {
try {
if(robot == null) robot = new Robot();
} catch (AWTException e1) {
e1.printStackTrace();
}
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) {
new Thread(() -> {
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
int screenshotX = f.getContentPane().getLocationOnScreen().x;
int screenshotY = f.getContentPane().getLocationOnScreen().y;
int screenshotWidth = f.getContentPane().getWidth();
int screenshotHeight = f.getContentPane().getHeight();
BufferedImage imageOutput = robot.createScreenCapture(new Rectangle(screenshotX, screenshotY, screenshotWidth, screenshotHeight));
try {
// write the image as a PNG
ImageIO.write(
imageOutput,
"png",
new File("CapturedImage.png"));
} catch(Exception e) {
e.printStackTrace();
}
}).start();
}
} );
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);
}
}
https://stackoverflow.com/questions/38858943
复制相似问题