Java 绘制后从 JPanel 保存图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19621105/
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
Save image from JPanel after draw
提问by ??ng Nguy?n
I'm newbie in jave, my first project is draw, and save a image from JPanel, my draw is done, but I cant save it after I draw in JPanel :(, So can you help me to fix it when I open the image after draw, It doesn't contain anything :( here my codes:
我是 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();
}
}
}
采纳答案by u6294745
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");
}
}
回答by nullptr
Create BufferedImage to store your painting. When you paint, paint on BufferedImage.
创建 BufferedImage 来存储您的绘画。绘画时,请在 BufferedImage 上绘画。
When you need to display paint on JPanel, draw BufferedImage on JPanel.
当需要在JPanel上显示paint时,在JPanel上绘制BufferedImage。
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();
}
}
回答by camickr
Screen Imageallows you to save an image of any component.
屏幕图像允许您保存任何组件的图像。
回答by Sage
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.
它所做的一切:它创建一个具有可见组件大小和ARGB
类型的图像,以支持透明度。然后它获取图形并将其传递给我们想要快照的组件。它绘制该组件的子组件,包括在其上绘制的任何内容。
Update:You can use component.print(Graphics g) too:
更新:您也可以使用 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);
But this function will draw only the rendered graphics of the component but not the child components. I have tested it.
但是这个函数只会绘制组件的渲染图形,而不是子组件。我已经测试过了。
Edit:
编辑:
- 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 averb
, it is a function. 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 aboutMyCanvas extends JPanel
- Inside the
panel
your first statementprivate paint my_paint;
: what is it doing here unnecessarily ? - your
saveFile()
function belongs to theJFrame
and you have created yourpanel
(on which you are drawing) local to the frame constructor. How should thesaveFile()
function have access to it? Declare your painting Panel in the JFrame class context aspublic
orprivate
. I have written in a meaningful way to read the sizes of the component using
getWidth()
andgetHeight()
But you are writing:BufferedImage image2 = new BufferedImage(panel.WIDTH, panel.HEIGHT, ...);
- 你的
paint extends JFrame
班级可以有一个好听的名字,例如,PaintFrame extends JFrame
。类名不应该有函数名,paint 是一个verb
,它是一个函数。 panel extends JPanel
: 为什么我们要往下选择首字母小写的类名?我们可以给我们的组件命名来反映我们正在用它做什么:比如,我们正在绘制,那么呢?MyCanvas extends JPanel
- 在
panel
您的第一个声明中private paint my_paint;
:它在这里不必要地做什么? - 您的
saveFile()
函数属于JFrame
并且您已经在panel
框架构造函数的本地创建了您的(您正在绘制的)。saveFile()
函数应该如何访问它?在 JFrame 类上下文中将您的绘画面板声明为public
或private
。 我以一种有意义的方式编写了使用
getWidth()
and读取组件大小的方法,getHeight()
但是您正在编写: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.
我再次完整地编写了如何将图像保存为png
usingImageIO.write(image, "png", "myFile.png")
函数的代码。请仔细阅读答案。
Following resources might be helpful:
以下资源可能会有所帮助: