Java将2D图形作为参数传递
我有一个功能,画一个图像,然后立即保存,但问题是它似乎画了两次,一次是为了屏幕上的视图,然后一次是保存到磁盘上Java将2D图形作为参数传递,java,swing,output,graphic,Java,Swing,Output,Graphic,我有一个功能,画一个图像,然后立即保存,但问题是它似乎画了两次,一次是为了屏幕上的视图,然后一次是保存到磁盘上 public class myFrame { public static void main(String[] args) { JFrame lv_frame = new JFrame(); // setup jframe here lv_frame.add(new image()); lv_frame.s
public class myFrame {
public static void main(String[] args) {
JFrame lv_frame = new JFrame();
// setup jframe here
lv_frame.add(new image());
lv_frame.setVisible(true);
}
}
class image extends JPanel {
public void paintComponent(Graphics graphic) {
super.paintComponent(graphic);
draw(graphic);
save();
}
public void draw(Graphics graphic) {
Graphics2D graphic2D = (Graphics2D) graphic;
graphic2D.fillArc(0, 0, 250, 250, 0, 90);
}
public void save() {
BufferedImage image = new BufferedImage(250, 250, BufferedImage.TYPE_4BYTE_ABGR_PRE);
Graphics2D graphic2D = image.createGraphics();
try {
File output = new File("file.png");
// is it possible to use the graphic I've already
// drawn here instead of re-drawing?
draw(graphic2D);
ImageIO.write(image, "png", output);
} catch(IOException log) {
System.out.println(log);
}
}
}
我有一个函数draw,它在gui屏幕上创建图像,还有一个函数save,它将图像保存到磁盘,但save函数也调用draw
是否可以保存已绘制的图像,而无需重新调用绘图功能,就像在我的代码中所做的那样?更改创建graphics2D对象的位置并重新使用它
试试这个
编辑 我在另一篇文章中找到了答案。画两次这幅画不是个坏主意。正如@Hovercraft在中所说,您正在做的是将屏幕绘图与写入文件分离,这样您就不会看到图形绘图性能受到影响 我只尝试过绘制一次图形,但您没有简单的方法来存储图形对象。可能是为了防止这种情况。如果您看到了该方法的工作方式,您将获得图形对象,其唯一目的是在其上绘制。以其他方式使用它可能会影响性能 更改创建graphics2D对象的位置并重新使用它 试试这个
编辑 我在另一篇文章中找到了答案。画两次这幅画不是个坏主意。正如@Hovercraft在中所说,您正在做的是将屏幕绘图与写入文件分离,这样您就不会看到图形绘图性能受到影响 我只尝试过绘制一次图形,但您没有简单的方法来存储图形对象。可能是为了防止这种情况。如果您看到了该方法的工作方式,您将获得图形对象,其唯一目的是在其上绘制。以其他方式使用它可能会影响性能 我是在上回答你的问题的,但可能是因为你的问题性质类似,所以它被关闭了。 我认为有几个问题你似乎感到困惑,我想在这里写下我的解决方案,在你的重复文章中也解决了你的问题
是否可以保存已绘制的图像,而无需像在我的代码中那样重新调用draw函数 不要混淆在面板上绘制图像和保存图像。下面显示了保存绘制图像的工作示例
class DrawingSpace extends JPanel
{
private BufferedImage buf;
public DrawingSpace(){
setPreferredSize(new Dimension(200, 200));
buf = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
drawOnBuffer();
}
public void drawOnBuffer(){
Graphics g = buf.createGraphics();
g.setColor(Color.BLUE);
g.fillOval(0,0,200,200);
g.setColor(Color.RED);
g.fillOval(50,50,100,100);
g.dispose();
}
public void saveBufferAsImage(String pathname){
String fmt = "";
if(!(pathname == null || pathname.equals(""))){
fmt = pathname.substring(pathname.lastIndexOf(".")+1);
File outputfile = new File(pathname);
try{
ImageIO.write(buf, fmt, outputfile);
}catch(IOException ioe){System.out.println("Unable to save file");}
}
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(buf, 0, 0, 200, 200, null); //Only for user to see
}
}
要保存图像,不一定要先在JPanel中绘制并显示图像。请注意,我创建了一个名为buf
的BufferedImage
,我正在buf
上绘图。一旦我绘制了一个缓冲区图像
,我就可以简单地将该图像保存为一个文件(我不必先将其绘制到面板)
请注意,我做了以下操作:
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(buf, 0, 0, 200, 200, null); //Only for user to see
}
g.drawImage(buf,0,0,200,200,null)
将buf
上的任何内容绘制到JPanel上。它可以被删除,并且保存仍然有效。当我在面板上绘制时,用户只能看到绘制的结果
要测试程序,请执行以下操作:
class SaveImageRunner{
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
JFrame frame = new JFrame("Saving a buffered image");
DrawingSpace ds = new DrawingSpace();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(ds);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
ds.saveBufferAsImage("BlueCircle.png");
}
});
}
}
保存的图像:
绘图上的一些指针:
应仅包含图纸代码,而不包含其他代码。不要在此处执行将图像保存到文件的代码paintComponent(Graphics)
- 尽量不要在
中创建新的缓冲区图像。否则,将在每次重新绘制时创建BuffereImage的新实例paintComponent(Graphics)
是否可以保存已绘制的图像,而无需像在我的代码中那样重新调用draw函数 不要混淆在面板上绘制图像和保存图像。下面显示了保存绘制图像的工作示例
class DrawingSpace extends JPanel
{
private BufferedImage buf;
public DrawingSpace(){
setPreferredSize(new Dimension(200, 200));
buf = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
drawOnBuffer();
}
public void drawOnBuffer(){
Graphics g = buf.createGraphics();
g.setColor(Color.BLUE);
g.fillOval(0,0,200,200);
g.setColor(Color.RED);
g.fillOval(50,50,100,100);
g.dispose();
}
public void saveBufferAsImage(String pathname){
String fmt = "";
if(!(pathname == null || pathname.equals(""))){
fmt = pathname.substring(pathname.lastIndexOf(".")+1);
File outputfile = new File(pathname);
try{
ImageIO.write(buf, fmt, outputfile);
}catch(IOException ioe){System.out.println("Unable to save file");}
}
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(buf, 0, 0, 200, 200, null); //Only for user to see
}
}
要保存图像,不一定要先在JPanel中绘制并显示图像。请注意,我创建了一个名为buf
的BufferedImage
,我正在buf
上绘图。一旦我绘制了一个缓冲区图像
,我就可以简单地将该图像保存为一个文件(我不必先将其绘制到面板)
请注意,我做了以下操作:
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(buf, 0, 0, 200, 200, null); //Only for user to see
}
g.drawImage(buf,0,0,200,200,null)
将buf
上的任何内容绘制到JPanel上。它可以被删除,并且保存仍然有效。当我在面板上绘制时,用户只能看到绘制的结果
要测试程序,请执行以下操作:
class SaveImageRunner{
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
JFrame frame = new JFrame("Saving a buffered image");
DrawingSpace ds = new DrawingSpace();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(ds);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
ds.saveBufferAsImage("BlueCircle.png");
}
});
}
}
保存的图像:
绘图上的一些指针:
应仅包含图纸代码,而不包含其他代码。不要在此处执行将图像保存到文件的代码paintComponent(Graphics)
- 尽量不要在
中创建新的缓冲区图像。否则,将在每次重新绘制时创建BuffereImage的新实例paintComponent(Graphics)