Java Canvas 从 BufferedImage 绘制图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22431620/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 15:40:20  来源:igfitidea点击:

Java Canvas Draw Image from BufferedImage

javaimagefilecanvas

提问by user3424580

I am currently working on my personal project. The idea is to import a picture and crop it into n-pieces of bufferedimage then draw them with random sequence to a java canvas. After that save the canvas to image file. Right now iam stuck at saving the canvas and i have searching for the solutions but none of them work. Here my save procedure. Please help, thanks in advance

我目前正在做我的个人项目。这个想法是导入一张图片并将其裁剪成 n 块缓冲图像,然后用随机序列将它们绘制到 Java 画布上。之后将画布保存为图像文件。现在我坚持保存画布,我一直在寻找解决方案,但没有一个工作。这是我的保存程序。请帮忙,提前致谢

 private void save() {    
    int r = jFileChooser1.showSaveDialog(this);
    File file2 = null; 
    if(r == jFileChooser1.APPROVE_OPTION){
    file2 = jFileChooser1.getSelectedFile();

    Graphics g2d = canvas.getGraphics();    
    BufferedImage bi = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);  
    Graphics2D g2 = bi.createGraphics();
    canvas.paint(g2);  
    g2.dispose();  
    g2d.dispose();
    try  
    {  
        ImageIO.write(bi, "jpg", file2);  
    }  
    catch (Exception ex) {
        System.out.println("Error saving");
    }
    }
}

Update : Now i get it, after using paintComponents now i can save the picture. Thanks @madProgrammer

更新:现在我明白了,在使用paintComponents之后,我可以保存图片了。谢谢@madProgrammer

public class CaptureImage extends javax.swing.JFrame {

MyPanel canvas;
BufferedImage[] processedImage;


public CaptureImage(BufferedImage[] proc) {
    processedImage = proc;
    SwingUtilities.invokeLater(new Runnable() {

        public void run() {
            createAndShowGUI();
        }
    });

}

private void createAndShowGUI() {
    System.out.println("Created GUI on EDT? "
            + SwingUtilities.isEventDispatchThread());
    JFrame f = new JFrame("Output Picture");
    f.addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent e){
                save();
                System.exit(0);//cierra aplicacion
            }
        });
    canvas = new MyPanel(processedImage);
    f.add(canvas);
    f.setSize(400, 400);
    f.setVisible(true);
}

public void save() {
    JFileChooser jFileChooser1 = new JFileChooser();
    int r = jFileChooser1.showSaveDialog(this);
    File file2 = null;
    if (r == jFileChooser1.APPROVE_OPTION) {
        file2 = jFileChooser1.getSelectedFile();

        BufferedImage bi = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = bi.createGraphics();
        canvas.print(g2);

        try {
            ImageIO.write(bi, "jpg", file2);
            g2.dispose();
        } catch (Exception ex) {
            System.out.println("Error saving");
        }
    }
}
}


 class MyPanel extends JPanel {

private Image[] processedImage;

public MyPanel(Image[] processedImage) {
    this.processedImage = processedImage;

    addMouseListener(new MouseAdapter() {

        public void mousePressed(MouseEvent e) {
            repaint();
        }
    });

}

public Dimension getPreferredSize() {
    return new Dimension(300, 300);
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    int loopj = 10;
    int loopi = 10;
    int l = 0;
    int jPieces = 100;
    int[] r = new int[jPieces];
    int rand = 0;
    for (int i = 0; i < r.length; i++) {
        rand = (int) (Math.random() * (r.length));
        if (Arrays.binarySearch(r, 0, r.length, rand) <= -1) {
            r[i] = rand;
        }
    }
    Graphics2D g2d = (Graphics2D) g;
    for (int i = 0; i < loopi; i++) {
        for (int j = 0; j < loopj; j++) {
            g2d.drawImage(processedImage[r[l]], i * 30, j * 30, this);
            l++;
        }
    }
}
}

采纳答案by MadProgrammer

There's no need to use getGraphicsand you certainly shouldn't be disposing of it.

没有必要使用getGraphics,你当然不应该处理它。

Instead of using paint, which could include double buffering, you should try using printAll

而不是 using paint,其中可能包括双缓冲,您应该尝试使用printAll

BufferedImage bi = new BufferedImage(canvas.getWidth(), canvas.getHeight(), BufferedImage.TYPE_INT_RGB);  
Graphics2D g2 = bi.createGraphics();
canvas.printAll(g2);  
g2.dispose();  

See Component#printAllfor more details.

有关Component#printAll更多详细信息,请参阅。

You should also be using the size of the canvasto determine the size of the image. The above example assumes that the canvashas already been sized appropriately...

您还应该使用 的大小canvas来确定图像的大小。上面的例子假设canvas已经适当地调整了大小......