Java将2D图形作为参数传递

时间:2016-02-29 10:07:48

标签: java swing output graphic

我有一个绘制图像的功能,然后立即保存它,但问题是它似乎是两次绘制,一次用于屏幕上的视图然后一次将其保存到磁盘

public class myFrame {

    public static void main(String[] args) {

        JFrame lv_frame = new JFrame();
        // setup jframe here

        lv_frame.add(new image());

        lv_frame.setVisible(true);

    }

}

class image extends JPanel {

    public void paintComponent(Graphics graphic) {

        super.paintComponent(graphic);
        draw(graphic);
        save();

    }

    public void draw(Graphics graphic) {

        Graphics2D graphic2D = (Graphics2D) graphic;
        graphic2D.fillArc(0, 0, 250, 250, 0, 90);

    }

    public void save() {

        BufferedImage image = new BufferedImage(250, 250, BufferedImage.TYPE_4BYTE_ABGR_PRE);
        Graphics2D graphic2D = image.createGraphics();

        try {
            File output = new File("file.png");

            // is it possible to use the graphic I've already
            // drawn here instead of re-drawing?
            draw(graphic2D);

            ImageIO.write(image, "png", output);
        } catch(IOException log) {
            System.out.println(log);
        }

    }

}

我有一个在gui屏幕上创建图像的函数绘制和另一个将它保存到磁盘的函数save,但是save函数也调用了draw。

是否可以保存已经绘制的图像而无需重新调用绘图功能,因为它在我的代码中完成了?

2 个答案:

答案 0 :(得分:3)

我在Display to GUI and Save to Disk with a Single Object/Variable上回答了你的问题,但是由于问题的类似性质,它已经关闭了。 我认为有几个问题你似乎感到困惑,我想在这里编写我的解决方案,这也解决了你在重复帖子中提出的问题。

  

是否可以保存已经绘制的图像而无需重新调用绘图功能,因为它在我的代码中完成了?

不要在面板上绘制图像和保存图像之间混淆。以下是保存绘制图像的工作示例。

class DrawingSpace extends JPanel
{
    private BufferedImage buf;

    public DrawingSpace(){
        setPreferredSize(new Dimension(200, 200));
        buf = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
        drawOnBuffer();
    }

    public void drawOnBuffer(){
        Graphics g = buf.createGraphics();
        g.setColor(Color.BLUE);
        g.fillOval(0,0,200,200);
        g.setColor(Color.RED);
        g.fillOval(50,50,100,100);
        g.dispose();
    }

    public void saveBufferAsImage(String pathname){
        String fmt = "";
        if(!(pathname == null || pathname.equals(""))){
            fmt = pathname.substring(pathname.lastIndexOf(".")+1);
            File outputfile = new File(pathname);
            try{
                ImageIO.write(buf, fmt, outputfile);        
            }catch(IOException ioe){System.out.println("Unable to save file");}
        }       
    }

    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(buf, 0, 0, 200, 200, null); //Only for user to see
    }
}

要保存图片, 不一定 必须先在JPanel中绘制并显示它。请注意,我创建了一个名为BufferedImage的{​​{1}},我正在使用buf。一旦我绘制到buf,我就可以将该图像保存为文件(我不必先将其绘制到面板中)。

请注意,我执行了以下操作:

BufferedImage

@Override public void paintComponent(Graphics g){ super.paintComponent(g); g.drawImage(buf, 0, 0, 200, 200, null); //Only for user to see } 会将g.drawImage(buf, 0, 0, 200, 200, null)上的内容绘制到JPanel上。它可以删除,保存 仍然有用 。当我在面板上绘制它时,只有用户才能看到绘图的结果。

测试程序:

buf

已保存的图片:

enter image description here

关于绘图的一些指示:

  • class SaveImageRunner{ public static void main(String[] args){ SwingUtilities.invokeLater(new Runnable(){ @Override public void run(){ JFrame frame = new JFrame("Saving a buffered image"); DrawingSpace ds = new DrawingSpace(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(ds); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); ds.saveBufferAsImage("BlueCircle.png"); } }); } } 只能包含绘图代码而不包含其他内容。不要实现将代码保存到此处文件中的代码。

  • 尽量不要在paintComponent(Graphics)中创建新的BufferedImage。如果没有,将在每次重绘时创建一个新的BufferedImage实例。

答案 1 :(得分:2)

更改创建graphics2D对象的位置并重复使用它。

试试这个。

\0


修改

我在另一篇文章中找到了答案。绘图两次并不是一个坏主意。你正在做的是像@Hovercraft在this post中所说的那样,将屏幕绘图与文件分离到文件中,这样你就不会看到你的图形绘制性能受到伤害。

我曾尝试只绘制一次绘图,但是没有简单的方法来存储绘图Graphics对象。可能是为了防止这种情况而实施的。如果您看到方法的工作方式,您将获得Graphics对象,其唯一目的是在其上绘制。以其他方式使用它可能会影响性能。