簡體   English   中英

Java BufferedImage從Canvas返回黑色圖像

[英]Java BufferedImage returns black image from Canvas

我一直在嘗試制作一個具有像工具這樣的畫筆的簡單程序,當打開該程序時,它創建了一個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) {

        }
    }
}

有什么想法可能導致這種情況?

這是錯誤的地方:

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

您獲取imageGraphics ,然后將image繪制到該Graphics 因此,基本上,您是在自己上繪制image

您想要的可能更像這樣:

            Graphics2D g2=(Graphics2D)image.getGraphics();
            canvas.print(g2);
            ...

現在,還要考慮以下注意事項:

  • 不要使用Canvas (AWT),而是改用JPanel (並重寫paintComponent )或JLabel一個BufferedImage (畫上了Graphics的的BufferedImage並調用repaint()JLabel )(擺動)
  • 不要在任何組件上使用getGraphics ,請使用paintComponent方法中提供的Graphics

我正在談論的小演示示例:

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

}
    // Create a buffered image:
    BufferedImage image=new BufferedImage(canvas.getWidth(), 
        canvas.getHeight(),BufferedImage.TYPE_INT_ARGB);

    // Get the g2 to draw with on the image:
    Graphics2D g2= (Graphics2D)image.getGraphics();

    // Let the canvas component do a paintComponent on the image:
    SwingUtilities.paintComponent(g2, canvas, frame, 0, 0,
        canvas.getWidth(), canvas.getHeight());

    ImageIO.write(image, "png", new File("C:\\test\\canvas.png"));

可以使用JPanel而不是Canvas(一個公認的誤導性名稱,尤其是現在使用HTML 5的名稱)。

在paintComponent中,必須完成所有如fillOval的繪制。 添加Shape-s或-容易嗎? -添加描述必須繪制的數據。

在Paint程序上有一些繪圖教程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM