首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么Linux平台上JFrame窗口的theBufferedImage输出看起来和屏幕上的不一样?

为什么Linux平台上JFrame窗口的theBufferedImage输出看起来和屏幕上的不一样?
EN

Stack Overflow用户
提问于 2016-08-10 03:29:33
回答 2查看 218关注 0票数 1

我正在做一个项目,需要捕获屏幕图形用户界面的图像数据(例如JFrame)。不知何故,我的应用程序可以在windows和Mac OS上工作,但对于Linux,它不能提供与屏幕上的GUI相同的图像输出。

代码语言:javascript
运行
复制
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

EN

回答 2

Stack Overflow用户

发布于 2016-08-10 05:00:30

Swing不会绘制整个框架。框架是操作系统的一个窗口小部件。

尝试使用Screen Image

当一个帧被指定为组件时,它将使用Robot类来获取图像。否则就是用秋千作画。

票数 1
EN

Stack Overflow用户

发布于 2016-08-11 05:53:06

快速解决方案

尝试更改...

代码语言:javascript
运行
复制
BufferedImage imageOutput = getImageData(f); 

代码语言:javascript
运行
复制
BufferedImage imageOutput = getImageData(f.getContentPane());

这可能也可以在Linux上工作(我现在不能测试它),并且可以很容易地解决你的问题。

解决方案

或者,您可以使用Robot类。Robot具有更兼容的屏幕捕获功能,但这意味着要对您的代码进行严重更改。你可以在我的答案的最下面找到代码。让我解释一下所有这些变化的原因。

  1. Robot是执行屏幕捕获所需的类。它可以捕获整个桌面,也可以捕获部分屏幕。在本例中,我们将通过找出桌面上各自的XY坐标,让它捕获应用程序的蓝色部分。在这种情况下,Robot需要是静态的,因为您试图通过main()方法访问它。因此,Robot变量需要在main()方法的外部,以便JMenuItemActionListener可以访问它。

  1. 如果您通过菜单执行屏幕捕获,则该菜单将出现在屏幕捕获中,因为您没有指定菜单消失的时间。因此,需要添加延迟。同时,这个延迟需要在一个单独的线程中发生,否则你的菜单将会冻结...我创建新线程的方式称为Lambda表达式。这只是一个简单的方法,可以轻松地创建一个立即启动的新线程,仅此而已。它是这样工作的:new Thread(() -> { /* Do something */ }.start();

  1. 下一步是找到屏幕蓝色部分的坐标。这是框架(或您希望捕获的任何组件)上下文窗格上的一个简单getLocationOnScreen()

  1. 现在,屏幕截图可以由Robot创建,并使用之前的代码保存到文件中。

就这样!如果你有任何问题,请发表评论,我稍后会再来查看。

代码

代码语言:javascript
运行
复制
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);
 }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38858943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档