Save image from JPanel after draw

陌路散爱 提交于 2019-11-29 05:06:22
刘远圳
private void saveImage(){
    BufferedImage imagebuf=null;
    try {
        imagebuf = new Robot().createScreenCapture(panel.bounds());
    } catch (AWTException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }  
     Graphics2D graphics2D = imagebuf.createGraphics();
     panel.paint(graphics2D);
     try {
        ImageIO.write(imagebuf,"jpeg", new File("save1.jpeg"));
    } catch (Exception e) {
        // TODO Auto-generated catch block
        System.out.println("error");
    }
}

Create BufferedImage to store your painting. When you paint, paint on BufferedImage.

When you need to display paint on JPanel, draw BufferedImage on JPanel.

This way, you can load / save painting to file.

Something like this:

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class Paint extends JPanel{
    private BufferedImage paintImage = new BufferedImage(500, 400, BufferedImage.TYPE_3BYTE_BGR);

    @Override
    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(paintImage, 0, 0, null);
    }

    // draw painting
    public void updatePaint(){
        Graphics g = paintImage.createGraphics();

        // draw on paintImage using Graphics

        g.dispose();
        // repaint panel with new modified paint
        repaint();
    }

    public void save() throws IOException{
        ImageIO.write(paintImage, "PNG", new File("filename.png"));
    }

    public void load() throws IOException {
        paintImage = ImageIO.read(new File("filename.png"));
        // update panel with new paint image
        repaint();
    }
}

There is a nice approach:

BufferedImage image = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
component.paint(g);
 try {
        ImageIO.write(image, "png", new File(filename));
    } catch (IOException ex) {
        Logger.getLogger(CustomApp.class.getName()).log(Level.SEVERE, null, ex);
   }

All what it does: It creates an image with visible component's size and ARGB type for transparency support. Then it get the graphics and pass that to the component we want to have snapshot of. It paints that component's child component including anything drawn on it.

Update: You can use component.print(Graphics g) too:

Dimension componentSize = component.getPreferredSize();
component.setSize(componentSize); // need to make sure that both sizes are equal
BufferedImage image = new BufferedImage(comonent.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = image.createGraphics();
g.fillRect(0, 0, image.getWidth(), image.getHeight());
component.print(g);

But this function will draw only the rendered graphics of the component but not the child components. I have tested it.


Edit:

  1. Your paint extends JFrame class can have a nice name, e.g., PaintFrame extends JFrame. Class name should not have a name of a function, paint is a verb, it is a function.
  2. panel extends JPanel : why should we go down choosing a class name with first letter of lower case? We can give our component name to reflect what we are doing with it: like, we are drawing so what about MyCanvas extends JPanel
  3. Inside the panel your first statement private paint my_paint; : what is it doing here unnecessarily ?
  4. your saveFile() function belongs to the JFrame and you have created your panel (on which you are drawing) local to the frame constructor. How should the saveFile() function have access to it? Declare your painting Panel in the JFrame class context as public or private.
  5. I have written in a meaningful way to read the sizes of the component using getWidth() and getHeight() But you are writing:

         BufferedImage image2 = new BufferedImage(panel.WIDTH, panel.HEIGHT, ...);
    

And again i have completely written the code how to save the image as a png using ImageIO.write(image, "png", "myFile.png") function. Please read the answers carefully.

Following resources might be helpful:

  1. A closer look at painting mechanism.
  2. Writing and saving images

Screen Image allows you to save an image of any component.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!