Saving Image of a jpanel
Hi
I'm trying to save an image of a jpanel, this jpanel is not rendered. I've tried using the following method:
BufferedImage image =new BufferedImage(panel.getPreferredSize().width ,panel.getPreferredSize().height, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
panel.paint(g);
ImageIO.write(image,"png",new File("myfile.png"));
But the components inside the panel do not show, only the background of the panel, also tried to use:
panel.print(g);
instead of the paint method, but the result is that all the components show on top of another.
If anybody can help me i would appreciate it.
# 1
You shouldn't call the paint method directly, but instead call repaint() and overload the paint method in your JPanel to perform the BufferedImage task that you wish to accomplish.
# 2
http://forum.java.sun.com/thread.jspa?threadID=604040
# 3
You might want to look on this one http://java.sun.com/docs/books/tutorial/2d/images/saveimage.html
# 4
maple_shaft,
Is it possible to use Fonseca's example above to show what you mean?
I am a newbie facing the same problem as he did.
I tried camickr's methods as well but it did not work (except for the print screen method) when i tried to save an image from BufferImage.
Please enlighten!
Thanks.
Shoker
# 5
Fonsecas problem was that he created a new instance of a BufferedImage and tried to obtain a graphics context from a new blank BufferedImage.
If you override the paint(Graphics g) method in your JPanel then the Graphics argument g contains the needed Graphics context to create an offscreen image.
With the offscreen image you use ImageIO to create an image file.
The links above should explain everything pretty clearly.
Post your code so we can see what you are doing wrong.
# 6
You shouldn't call the paint method directly, but instead call repaint() and overload the paint method in your JPanel to perform the BufferedImage task that you wish to accomplish.
Eh? There's no need to do this - such a strategy would mean that every UI component you wanted to render would have to contain specific behaviour.
Fonsecas problem was that he created a new instance of a BufferedImage and tried to obtain a graphics context from a new blank BufferedImage.
That's a perfectly reasonable thing to do, it's the normal way of going about this, and should not be the cause of his trouble. Without an SSCCE, it's hard to say what is.
If you override the paint(Graphics g) method in your JPanel then the Graphics argument g contains the needed Graphics context to create an offscreen image.
You don't need a Graphics object to create an Image. You can create it from the component's createImage() method, using a BufferedImage constructor, or via the GraphicsConfiguration, and so on.
# 7
If your panel isn't realized yet, you need to give it a concrete size, otherwise it's size is 0x0. You can set it's size to it's preferred size if that's what you want, but it may not look the same as if it were in realized on screen. The reason is that when you realize a component, it's size is determined by the LayoutManager and this may be different than the preferredi size.
# 8
maple_shaft,
Actually my codes are rather similar to Fonseca's as with those which I found on the Internet but i just cant get it to work. This is because my image saved was either black or white when i tried to save from buffer. It works for me when I used 'robot().screenCapture();' but i guess this isnt the appropriate method.
====================My codes=====================
Point p = new Point(0, 0);
SwingUtilities.convertPointToScreen(p, jPanel4);
Rectangle region = jPanel4.getBounds();
region.x = p.x;
region.y = p.y;
BufferedImage bi = new BufferedImage(region.width,region.height,BufferedImage.TYPE_INT_RGB);
g = bi.getGraphics();
g.drawString("\u7000",45,80);
jPanel4.paint( g );
g.dispose();
ImageIO.write(bi, getFileFormatString(), file);
====================My codes=====================
Shoker
# 9
Point p = new Point(0, 0);
SwingUtilities.convertPointToScreen(p, jPanel4);
Rectangle region = jPanel4.getBounds();
region.x = p.x;
region.y = p.y;
I'm not sure why you're doing this - p.x and p.y are never used so that's a load of wasted code. Just grab the size via getSize(), noting the above caveats about the default sizes of components being zero.
In case there's any confusion about bounds, components render themselves in their own co-ordinate space with 0,0 at top left; it's the parent container's job to translate the Graphics object according to the child's location.
# 10
maple_shaft,
I think my problem lies with the assignment of the drawn Unicode on the jPanel. Does anyone had any idea how do I go about assigning the contents drawn on the jPanel to the BufferedImage bi (offscreen image)? If this is settled, i dont think there are any problems saving it in a file.
Please enlighten me.
Thanks!
Shoker
# 11
Hi,
I did this because i thought that if i were to shift the window of my application, the coordinates changed. Therefore, when i tried to save the image to BufferedImage using screen capture formerly, it works. So I assume that this works for saving from buffer.
Formerly,
//Get the image size
Point p = new Point(0, 0);
SwingUtilities.convertPointToScreen(p, jPanel4);
Rectangle region = jPanel4.getBounds();
region.x = p.x;
region.y = p.y;
BufferedImage bi = new Robot().createScreenCapture( region );
This portion was learnt from Camickr's code. Didn't manage to get other parts to work for me except this. Guess I did it wrongly.
Shoker
# 12
maybe this can help u: http://www.developerdotstar.com/community/node/124/print
# 13
Hi,Thanks for all your assistance!Learnt something new and problem solved!Graphics allows drawString to be shown when drawn while Graphics2D doesnt do this. It draws the image on BufferedImage instead.Shoker
# 14
> Graphics allows drawString to be shown when drawn
> while Graphics2D doesnt do this. It draws the image
> on BufferedImage instead.
I think you may be confused about something still. The Graphics2D object is just a bigger, better Graphics object. Where a Graphics object draws has nothing to do with it's type, it has to do with where you got it from. Either it comes from an image or it comes from a component.