Java BufferedImage从Canvas返回黑色图像

Dan*_*nov 2 java swing bufferedimage image

我一直在尝试制作一个简单的程序,它有一个像工具一样的画笔,打开时它创建了一个JFrame,在其中我放置了一个Canvas,用户可以在其中绘制.现在,我正在尝试使用在退出时调用的saveCanvas方法来保存绘图,但无论我做什么,我都会得到一个黑色图像.这是我的代码:

public class Test{

    JFrame f;
    Canvas c;
    int x=-1, y=-1;

    public Test() {
        f = new JFrame();
        f.setSize(1200, 800);
        c = new Canvas(){
            @Override
            public void paint(Graphics g){
                super.paint(g);
            }
        };
        f.add(c);
        c.addMouseMotionListener(new MouseMotionListener(){    
            @Override
            public void mouseMoved(MouseEvent e) {
                // empty
            }
            @Override
            public void mouseDragged(MouseEvent e){
                if(x==-1){
                   x = e.getX();
                   y = e.getY();
                }
               c.getGraphics().fillOval(x, y, 5, 5); 
               x = e.getX();
               y = e.getY();
            }
        });
        f.addWindowListener(new WindowAdapter(){
           @Override
           public void windowClosing(WindowEvent evt) {
                 onExit();
           }
           public void onExit() 
            {
                saveCanvas(c);
                System.exit(0);
            }
        });
        f.setVisible(true);
    }

    public static void main(String[] args) {

        Test paintBrush = new Test();
    } 
    public static void saveCanvas(Canvas canvas){

        BufferedImage image=new BufferedImage(canvas.getWidth(), canvas.getHeight(),BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2=(Graphics2D)image.getGraphics();
                boolean x = false;
                while(!x){
                    x = g2.drawImage(image, 0, 0, null);
                }
        try 
                {
                    ImageIO.write(image, "png", new File("C:\\test\\canvas.png"));
        } 
                catch (Exception e) {

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

关于可能导致这种情况的任何想法?

Gui*_*let 5

这是错的:

            Graphics2D g2=(Graphics2D)image.getGraphics();
            boolean x = false;
            while(!x){
                x = g2.drawImage(image, 0, 0, null);
            }
Run Code Online (Sandbox Code Playgroud)

你拿走了Graphics,image然后你就image可以了Graphics.所以基本上,你正在image自我绘制.

你想要的可能更像是这样的:

            Graphics2D g2=(Graphics2D)image.getGraphics();
            canvas.print(g2);
            ...
Run Code Online (Sandbox Code Playgroud)

现在,请考虑以下说明:

  • 不要使用Canvas(AWT),而是使用JPanel(和覆盖paintComponent)或JLabelBufferedImage(借鉴GraphicsBufferedImage,并呼吁repaint()JLabel)(摇摆)
  • 不要getGraphics在任何组件上使用,请使用方法中Graphics提供的paintComponent

我正在谈论的小演示示例:

import java.awt.Desktop;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class Test {

    JFrame f;
    JLabel c;
    BufferedImage image;
    int x = -1, y = -1;

    public Test() {
        f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        image = new BufferedImage(1200, 800, BufferedImage.TYPE_INT_ARGB);
        c = new JLabel(new ImageIcon(image));

        f.add(c);
        c.addMouseMotionListener(new MouseMotionListener() {
            @Override
            public void mouseMoved(MouseEvent e) {
                // empty
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                if (x == -1) {
                    x = e.getX();
                    y = e.getY();
                }
                image.getGraphics().fillOval(x, y, 5, 5);
                c.repaint();
                x = e.getX();
                y = e.getY();
            }
        });
        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent evt) {
                onExit();
            }

            public void onExit() {
                try {
                    File output = new File("C:\\test\\canvas.png");
                    if (!output.getParentFile().exists()) {
                        output.getParentFile().mkdirs();
                    }
                    ImageIO.write(image, "png", output);
                    Desktop.getDesktop().open(output);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
        f.pack();
        f.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {

                Test paintBrush = new Test();
            }
        });
    }

}
Run Code Online (Sandbox Code Playgroud)