So I am trying to get a screen shot of my panel and the code below does perfect. I want to lower the starting point of the screenshot by like 200 pixels. If I do size.height-200 it raises the bottom . I will need to do that in the future but how do I lower the top too? Or will I need to do a different method?
System.out.println("Trying to screenshot");
Dimension size = getSize ();
BufferedImage img = new BufferedImage (size.width, size.height, BufferedImage.TYPE_3BYTE_BGR);
Graphics g = img.getGraphics ();
paint (g);
g.dispose ();
try
{
ImageIO.write (img, "png", new File ("screenshot1.png"));
}
catch (IOException ex)
{
ex.printStackTrace ();
}
Do you want to draw a component with an offset? If yes, then AffineTransformation is your friend. Try calling
Graphics2D g = img.createGraphics();
g.transform(AffineTransform.getTranslateInstance(0, -200));
paint(g);
g.dispose();
You can use the Screen Image class. It allows you to specify a Rectangle when creating an image of the panel.
If you don't want to use the class, then take at look at the code. For your requirement the key is to translate the graphics before you do the painting.
Related
How do you convert a JPanel to a File? My panel has a moving Image and I want to get individual frames.
You can create a BufferedImage of the panel at different points in time and then save the image to a file.
The basic logic for this would be:
BufferedImage image = new BufferedImage(panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
panel.print( g2d );
g2d.dispose();
ImageIO.write(...);
Check out the Screen Image class for convenience methods that implement the above functionality.
Of course this won't be very efficient since you need a completely new image for each frame.
I've made a code to draw on a Jpanel
frame1.add( new JPanel() {
public void paintComponent( Graphics g ) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.white);
g2.fillRect(0, 0, width, height);
//Drawnig Part
});
Every thing is OK
Now My question is how to save what I've drawn on my JPanel in a file a.PNG or any other type
I have spent a lot of time to write the Drawing Part, So it will be helpful if you can suggest a solution by changing the required parts of my code, instead of rewriting the whole code.
I suggest that you buffer your drawing operations with a BufferedImage, like so:
// This should not be done in the draw method, but rather when
// the frame is created. You should also make a new buffer image when
// the frame is resized. `frameWidth` and `frameHeight` are the
// frame's dimensions.
BufferedImage bufferImage = new BufferedImage(frameWidth, frameHeight,
BufferedImage.TYPE_INT_ARGB);
Graphics2D bufferGraphics = bufferImage.createGraphics();
// In your draw method, do the following steps:
// 1. Clear the buffer:
bufferGraphics.clearRect(0, 0, width, height);
// 2. Draw things to bufferGraphics...
// 3. Copy the buffer:
g2.drawImage(bufferImage, null, 0, 0);
// When you want to save your image presented in the frame, call the following:
ImageIO.write(bufferImage, "png", new File("frameImage.png"));
The Java Tutorial on Creating and Drawing to an Image, along with the ImageIO API reference might be helpful should you require more information.
Have a look at Writing/Saving an Image for more details, but essentially you can do something like...
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
// Draw what ever you want to to the graphics context
g2d.dispose();
ImageIO.write(img, "png", new File("My Awesome Drawing.png"));
If you can't separate the drawing logic from your panel, you could simply use the Graphics context from the BufferedImage to paint the the component with.
Have a look at Exporting a JPanel to an image and Print the whole program layout for examples
I have a JScrollPane with a JPanel where I can draw by mouse and code.
I need the possibility to zoom on details in my drawing.
But soon I get a outOfMemoryError. I think because I make my drawing to big while zooming.
This is my code:
private BufferedImage _bufferedImage;
private int _panelWidth = 2000, _panelHeight = 1500;
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
if(_bufferedImage != null){
g.drawImage(_bufferedImage, 0, 0, this);
}
}
public void draw(float zoomFactor){
try {
int width = (int)(_panelWidth * zoomFactor);
int height = (int)(_panelHeight * zoomFactor);
_bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = _bufferedImage.createGraphics();
g2.setBackground(Color.WHITE);
g2.setPaint(Color.BLACK);
g2.scale(zoomFactor, zoomFactor);
drawHouse(g2); ...
g2.dispose();
}
catch (Exception e) {
e.printStackTrace();
}
repaint();
}
There must be better practice then what I did.
I can just draw the area of the scrollpane, but then I can't use the scrollbars,
then I have to use buttons with arrow up, right, left, down to scroll in my drawing.
Anyone who can me give a hint?
but then I can't use the scrollbars
Scrollbars work when the preferred size of the component is greater than the size of the scrollpane. If you are zooming the image in the paintComponent() method then you would also need to override the getPreferredSize() method to return the appropriate size of the image that takes into account the zooming factor.
So in your case the preferred size would be the size of your image.
If you want to zoom in, I am assuming you are no trying to make "bigger pixels", but to draw the same figures at a higher scale. In that case, you should not be using a BufferedImage at all -- instead, you should draw to a suitably scaled JPanel or similar. You can always take a snapshot of whatever you are rendering whenever you need it; but rendering to a BufferedImage without need is wasteful (of time and memory).
See this answer for details.
I have made a JLabel where I display my images like this:
BufferedImage myimage;
imageLabel.setIcon(new ImageIcon(myimage));
Is it possible to draw an image and draw upon it a smaller image (an icon) with the setIcon command? How can I do it?
For example:
BufferedImage myimage1;
BufferedImage myLittleIcon;
imageLabel.setIcon(new ImageIcon(myimage1));
imageLabel.setIcon(new ImageIcon(myLittleIcon));
The above just draws the small icon.
Calling setIcon would overwrite the icon. However, you could try something like this:
// Assumed that these are non-null
BufferedImage bigIcon, smallIcon;
// Create a new image.
BufferedImage finalIcon = new BufferedImage(
bigIcon.getWidth(), bigIcon.getHeight(),
BufferedImage.TYPE_INT_ARGB)); // start transparent
// Get the graphics object. This is like the canvas you draw on.
Graphics g = finalIcon.getGraphics();
// Now we draw the images.
g.drawImage(bigIcon, 0, 0, null); // start at (0, 0)
g.drawImage(smallIcon, 10, 10, null); // start at (10, 10)
// Once we're done drawing on the Graphics object, we should
// call dispose() on it to free up memory.
g.dispose();
// Finally, convert to ImageIcon and apply.
imageLabel.setIcon(new ImageIcon(finalIcon));
This creates a new image, paints the big icon, and then paints the small icon.
You can also paint other things, like outlining a rectangle or filling an oval.
For more advanced graphics functions, try casting to a Graphics2D object.
When I'm rendering a Swing component to an image the fonts are different then when the component is rendered on screen. Here is an image showing the difference:
And this is the code:
public static BufferedImage renderComponent(Component component) {
int width = component.getWidth();
int height = component.getHeight();
BufferedImage buffImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) buffImage.getGraphics();
g.setFont(component.getFont());
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
component.paint(g);
g.dispose();
return buffImage;
}
What should I change to make a perfect screen shot of a Swing component? (The app is running on Windows 7)
What should I change to make a perfect screen shot of a Swing component?
I would guess you should not be providing rendering hints.
I use the Screen Image class for this (it is basically your code with a few other features built in).
After comparing the ScreenImage class (suggested by camickr) I found the cause of the problem. If I create a BufferedImage with the type set to TYPE_INT_RGB instead of TYPE_INT_ARGB the fonts are fine.
Class Robot
public synchronized BufferedImage createScreenCapture(Rectangle screenRect)
?