绘制后从JPanel保存图像

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

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

在此处输入图像描述

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

有一个很好的方法:

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

它所做的一切:它创建一个具有可见组件大小和ARGB类型的图像,以提供透明度支持。 然后它获取图形并将其传递给我们想要快照的组件。 它绘制组件的子组件,包括在其上绘制的任何内容。

更新:您也可以使用component.print(Graphics g):

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

但是此函数将仅绘制组件的渲染图形,而不绘制子组件。 我测试过了。


编辑:

  1. 你的paint extends JFrame类可以有一个很好的名字,例如, PaintFrame extends JFrame 。 类名不应该有函数名,paint是verb ,它是函数。
  2. panel extends JPanel :我们为什么要选择一个小写首字母的类名呢? 我们可以给出我们的组件名称以反映我们正在用它做什么:比如,我们正在绘制,那么MyCanvas extends JPanel
  3. panel你的第一个语句private paint my_paint; :这里不必要的是什么?
  4. 你的saveFile()函数属于JFrame ,你已经在框架构造函数的本地创建了panel (你正在绘制它)。 saveFile()函数应该如何访问它? 在JFrame类上下文中将您的绘图Panel声明为publicprivate
  5. 我用有意义的方式编写了使用getWidth()getHeight()读取组件的大小但是你写的是:

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

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

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

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

屏幕图像允许您保存任何组件的图像。