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

Java将2D图形作为参数传递,java,swing,output,graphic,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.s

我有一个功能,画一个图像,然后立即保存,但问题是它似乎画了两次,一次是为了屏幕上的视图,然后一次是保存到磁盘上

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);
        }

    }

}
我有一个函数draw,它在gui屏幕上创建图像,还有一个函数save,它将图像保存到磁盘,但save函数也调用draw

是否可以保存已绘制的图像,而无需重新调用绘图功能,就像在我的代码中所做的那样?

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

试试这个


编辑 我在另一篇文章中找到了答案。画两次这幅画不是个坏主意。正如@Hovercraft在中所说,您正在做的是将屏幕绘图与写入文件分离,这样您就不会看到图形绘图性能受到影响

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

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

试试这个


编辑 我在另一篇文章中找到了答案。画两次这幅画不是个坏主意。正如@Hovercraft在中所说,您正在做的是将屏幕绘图与写入文件分离,这样您就不会看到图形绘图性能受到影响

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

我是在上回答你的问题的,但可能是因为你的问题性质类似,所以它被关闭了。 我认为有几个问题你似乎感到困惑,我想在这里写下我的解决方案,在你的重复文章中也解决了你的问题


是否可以保存已绘制的图像,而无需像在我的代码中那样重新调用draw函数

不要混淆在面板上绘制图像和保存图像。下面显示了保存绘制图像的工作示例

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中绘制并显示图像。请注意,我创建了一个名为
buf
BufferedImage
,我正在
buf
上绘图。一旦我绘制了一个
缓冲区图像
,我就可以简单地将该图像保存为一个文件(我不必先将其绘制到面板)

请注意,我做了以下操作:

    @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)
buf
上的任何内容绘制到JPanel上。它可以被删除,并且保存仍然有效。当我在面板上绘制时,用户只能看到绘制的结果

要测试程序,请执行以下操作:

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)
    应仅包含图纸代码,而不包含其他代码。不要在此处执行将图像保存到文件的代码

  • 尽量不要在
    paintComponent(Graphics)
    中创建新的缓冲区图像。否则,将在每次重新绘制时创建BuffereImage的新实例

我是在上回答您的问题的,但可能是因为您的问题性质类似,所以关闭了。 我认为有几个问题你似乎感到困惑,我想在这里写下我的解决方案,在你的重复文章中也解决了你的问题


是否可以保存已绘制的图像,而无需像在我的代码中那样重新调用draw函数

不要混淆在面板上绘制图像和保存图像。下面显示了保存绘制图像的工作示例

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中绘制并显示图像。请注意,我创建了一个名为
buf
BufferedImage
,我正在
buf
上绘图。一旦我绘制了一个
缓冲区图像
,我就可以简单地将该图像保存为一个文件(我不必先将其绘制到面板)

请注意,我做了以下操作:

    @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)
buf
上的任何内容绘制到JPanel上。它可以被删除,并且保存仍然有效。当我在面板上绘制时,用户只能看到绘制的结果

要测试程序,请执行以下操作:

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)
    应仅包含图纸代码,而不包含其他代码。不要在此处执行将图像保存到文件的代码

  • 尽量不要在
    paintComponent(Graphics)
    中创建新的缓冲区图像。否则,将在每次重新绘制时创建BuffereImage的新实例


您是否尝试在构造函数中调用image.createGraphics()并将其传递给draw方法?我甚至不知道从何处开始使用该o_o“是否可以保存已绘制的图像,而不必像在我的代码中那样重新调用draw函数?”-只有您先绘制到图像,然后在component@Trent请看我下面的解决方案。您是否尝试在构造函数中调用image.createGraphics()并将其传递给draw方法?我甚至不知道从何处开始“是否可以将图像保存到