【问题标题】:Java - saving JPanel as an imageJava - 将 JPanel 保存为图像
【发布时间】:2014-09-03 18:41:10
【问题描述】:

我遇到了一个热门问题。我已经阅读了很多关于它的内容,但我仍然无法解决它。我正在编写类似 MSW Logo(Turtle 图形解释器)的代码,我想保存我的图像(绘制在扩展 JPanel 的类上)。问题是保存的图像是空白的(只有白色背景,仅此而已,没有形状)。

从 StackOverflow 上的帖子中我注意到,在 JPanel 上绘图是错误的,我应该在 BufferedImage 上绘图,但我不知道如何将此技巧应用于我的源代码。请帮助我离开地面。非常感谢! :)

我的类扩展 JPanel:

public class TurtlePanel extends JPanel {

    public TurtlePanel() {
        super();
        this.setPreferredSize(new Dimension(481, 481));
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
    }

}

创建面板:

public class PanelView {

    private JPanel panel;
    private MainWindowView mainView;


    public PanelView(MainWindowView mainView) {
        this.mainView = mainView;
        createView();
    }

    private void createView() {
        panel = new TurtlePanel();
        panel.setBounds(280, 30, 481, 481);
        panel.setBackground(Color.WHITE);
        panel.setVisible(true);
        mainView.mainWindow.add(panel);
    }

    public JPanel getPanel() {
        return this.panel;
    }

}

我绘制形状的方式(它有效,形状显示在我的面板上):

private void drawCircle(double radius) {
    if(Math.signum(radius) == -1)
        throw new NumberFormatException();

    if(turtleModel.isShown()) {
        Graphics2D g = ((Graphics2D) panelView.getPanel().getGraphics());
        g.setColor(turtleModel.getPenColor());
        g.draw(new Ellipse2D.Double(turtleModel.getPosX() - radius, turtleModel.getPosY() - radius, 2*radius, 2*radius));
    }
}

我尝试保存图像的方式:

try {
    BufferedImage image = new BufferedImage(panelView.getPanel().getWidth(), panelView.getPanel().getHeight(), BufferedImage.TYPE_INT_RGB);
    Graphics graphics = image.getGraphics();
    panelView.getPanel().paint(graphics);
    ImageIO.write(image, ext, new File(path));
} 
catch(IOException exc) {
    exc.printStackTrace();
}

再次感谢您的帮助!如果您需要更多信息,请告诉我。干杯!

【问题讨论】:

    标签: java jpanel bufferedimage


    【解决方案1】:

    调用 paint(graphics) 不会复制当前面板的内容。 这不是它应该的工作方式。

    通常,您将摇摆组件添加到 JPanel,调用 paintComponents() 将调用 JPanel 中包含的每个组件的 paint()

    您不应该直接绘图,而是可以修改 TurtlePanel,使其拥有他必须对 Graphics 对象执行的操作的列表,并覆盖它的 paint() 方法,以便它始终可以从全新打印它的全部内容图形对象。

    显然,对于专业的架构,您可能会想到更好的方法。

    【讨论】:

    • 非常感谢!现在我大概知道如何修复我的画了。
    【解决方案2】:

    在 JPanel 上绘图非常好。如果您经常重绘,而这些重绘绘制的是相同的东西,那么您可能希望将图形缓存在 BufferedImage 中。

    我不确定您当前的渲染是如何完成的,因为它似乎对可能是实例变量的 Graphics 对象进行操作,这很奇怪,因为您不想保存那些 Graphics 对象。以非标准(可能已损坏)的方式绘制图形最有可能给您带来麻烦。

    解决此问题的简单方法是创建一个更抽象的方法,该方法在传入的 Graphics 对象上绘制您希望呈现的内容。然后,JPanel 的 paintComponent 方法(使用其中的 Graphics 对象)和保存图片的代码(图片中的Graphics对象)都可以调用share同一个方法。

    【讨论】:

    • 谢谢!你是对的 - 我的绘画方式被打破了。
    猜你喜欢
    • 2011-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    相关资源
    最近更新 更多