绘制后从JPanel保存图像

Đăn*_*yễn 4 java swing bufferedimage

我是jave的新手,我的第一个项目是绘图,并从JPanel保存图像,我的绘图已经完成,但是在我绘制JPanel之后我无法保存它:(,所以当我打开它时你可以帮我解决它吗?绘制后的图像,它不包含任何东西:(这里我的代码:

package image;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;


public class paint extends JFrame{
private Point points[] = new Point[10000];
private Point pointends[] = new Point[10000];
private int pointCount = 0;
private JButton save_btn;
public paint()
{
    panel paint2 = new panel();
    add(paint2,BorderLayout.CENTER);
}
private class panel extends JPanel
{   
    private paint my_paint;
    public panel()
    {   
        setBackground(Color.WHITE);
        save_btn = new JButton();
        save_btn.setText("123");
        this.add(save_btn);
        ButtonHandler handler1 = new ButtonHandler();
        save_btn.addActionListener(handler1);
        MouseHandler handler = new MouseHandler();
        this.addMouseMotionListener(handler);

        this.addMouseListener(handler);
    }
    private class ButtonHandler implements ActionListener
    {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            savefile();
        }

    }
    @Override
    protected void paintComponent(Graphics g) 
    {
        // TODO Auto-generated method stub
        super.paintComponent(g);
        for(int i = 0;i <pointCount;i++)
        {   
            g.setColor(Color.RED);
            g.drawLine(points[i].x, points[i].y, pointends[i].x, pointends[i].y);
        }           
    }



private class MouseHandler extends MouseAdapter
{  
    @Override
    public void mouseDragged(MouseEvent e) 
    {
        // TODO Auto-generated method stub
            pointends[ pointCount-1] = e.getPoint();
            repaint();


    }
    @Override
    public void mousePressed(MouseEvent e) {
        // TODO Auto-generated method stub
        super.mousePressed(e);
        if(pointCount < points.length)
        {
            points[ pointCount ] = e.getPoint();
            pointends[ pointCount ] = e.getPoint();
            pointCount++; 
            repaint();
        }
    }
    @Override
    public void mouseReleased(MouseEvent e) {
        // TODO Auto-generated method stub
        super.mouseReleased(e);
        /*pointends[pointCount]=e.getPoint();
        repaint();
        pointCount++;
    */
    }

    }

}
public void savefile()
{
    BufferedImage image2 = new BufferedImage(panel.WIDTH, panel.HEIGHT,     BufferedImage.TYPE_INT_RGB);
    JFileChooser jFile = new JFileChooser();
    jFile.showSaveDialog(null);
    Path pth = jFile.getSelectedFile().toPath();
    JOptionPane.showMessageDialog(null, pth.toString());
    Graphics2D graphics2D = image2.createGraphics();
    try {
        ImageIO.write(image2, "", new File(pth.toString()));
    } catch (IOException ox) {
        // TODO: handle exception
        ox.printStackTrace();

}
}
}
Run Code Online (Sandbox Code Playgroud)

nul*_*ptr 12

创建BufferedImage以存储您的绘画.在绘画时,在BufferedImage上绘画.

当您需要在JPanel上显示绘画时,在JPanel上绘制BufferedImage.

这样,您可以加载/保存绘画到文件.

像这样的东西:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 6

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

片段代码的结果示例


Sag*_*age 5

有一个很好的方法:

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);
   }
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

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. panel你的第一个声明中private paint my_paint;:它在这里做了什么不必要的?
  4. 你的saveFile()函数属于JFrame你的,你已经创建了你的panel(你正在绘制的)框架构造函数的本地.该saveFile()功能应该如何访问它?在JFrame类上下文中将您的绘图面板声明为publicprivate.
  5. 我已经写了以有意义的方式使用读取组件的尺寸getWidth()getHeight()但是你写:

         BufferedImage image2 = new BufferedImage(panel.WIDTH, panel.HEIGHT, ...);
    
    Run Code Online (Sandbox Code Playgroud)

我再次完全编写了如何将图像保存为png使用ImageIO.write(image, "png", "myFile.png")函数的代码.请仔细阅读答案.

以下资源可能会有所帮助:

  1. 仔细看看绘画机制.
  2. 编写和保存图像