Is there a way to take a screenshot using Java and save it to some sort of image?
Solution 1
Believe it or not, you can actually use java.awt.Robot
to "create an image containing pixels read from the screen." You can then write that image to a file on disk.
I just tried it, and the whole thing ends up like:
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage capture = new Robot().createScreenCapture(screenRect);
ImageIO.write(capture, "bmp", new File(args[0]));
NOTE: This will only capture the primary monitor. See GraphicsConfiguration for multi-monitor support.
Solution 2
I never liked using Robot, so I made my own simple method for making screenshots of JFrame objects:
public static final void makeScreenshot(JFrame argFrame) {
Rectangle rec = argFrame.getBounds();
BufferedImage bufferedImage = new BufferedImage(rec.width, rec.height, BufferedImage.TYPE_INT_ARGB);
argFrame.paint(bufferedImage.getGraphics());
try {
// Create temp file
File temp = File.createTempFile("screenshot", ".png");
// Use the ImageIO API to write the bufferedImage to a temporary file
ImageIO.write(bufferedImage, "png", temp);
// Delete temp file when program exits
temp.deleteOnExit();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
Solution 3
If you'd like to capture all monitors, you can use the following code:
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] screens = ge.getScreenDevices();
Rectangle allScreenBounds = new Rectangle();
for (GraphicsDevice screen : screens) {
Rectangle screenBounds = screen.getDefaultConfiguration().getBounds();
allScreenBounds.width += screenBounds.width;
allScreenBounds.height = Math.max(allScreenBounds.height, screenBounds.height);
}
Robot robot = new Robot();
BufferedImage screenShot = robot.createScreenCapture(allScreenBounds);
Solution 4
public void captureScreen(String fileName) throws Exception {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle screenRectangle = new Rectangle(screenSize);
Robot robot = new Robot();
BufferedImage image = robot.createScreenCapture(screenRectangle);
ImageIO.write(image, "png", new File(fileName));
}
Solution 5
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] screens = ge.getScreenDevices();
Rectangle allScreenBounds = new Rectangle();
for (GraphicsDevice screen : screens) {
Rectangle screenBounds = screen.getDefaultConfiguration().getBounds();
allScreenBounds.width += screenBounds.width;
allScreenBounds.height = Math.max(allScreenBounds.height, screenBounds.height);
allScreenBounds.x=Math.min(allScreenBounds.x, screenBounds.x);
allScreenBounds.y=Math.min(allScreenBounds.y, screenBounds.y);
}
Robot robot = new Robot();
BufferedImage bufferedImage = robot.createScreenCapture(allScreenBounds);
File file = new File("C:\\Users\\Joe\\Desktop\\scr.png");
if(!file.exists())
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
ImageIO.write( bufferedImage, "png", fos );
bufferedImage will contain a full screenshot, this was tested with three monitors
jjnguy
About Me: I currently work for Design Center as a Sr. Software Engineer. Follow me on Twitter If you want to contact me personally, email me or send me a private message on twitter. jjnguy13 [at]gmail[dot] com
Updated on November 01, 2020Comments
-
jjnguy over 3 years
Simple as the title states: Can you use only Java commands to take a screenshot and save it? Or, do I need to use an OS specific program to take the screenshot and then grab it off the clipboard?
-
Chris Wagner about 14 yearsI wonder if this is what screen sharing applications like Elluminate (elluminate.com) use.
-
Simon Forsberg almost 12 yearsAny reason for why you're not liking Robot?
-
Dmitry Zagorulkin over 11 years@java_enthu actually yes, it will be work without console if you will hardcode path to screenshot in your app.
-
nullUser almost 11 yearsRobot does not include the mouse in the screen capture. Is there a similar function which does the exact same thing, but DOES include the mouse?
-
Mehdi Karamosly over 10 yearsis there a way to capture the mouse cursor as well ?!
-
DejanLekic over 10 yearsThink of it simply as a matter of taste.
-
Brad Mace almost 10 yearswould be better to calculate it this way
-
Brad Mace almost 10 yearsIt looks like this should have the advantage of working even if the target window is obscured before the screenshot is taken.
-
Brad Mace almost 10 yearsOn the other hand, this gets only the contents of the window, whereas with
Robot
you can also get the window's frame and titlebar. -
DejanLekic about 8 years@BradMace: that is a good point. I did not need the frame and titlebar, just the content...
-
Liam Larsen almost 7 yearsI did a benchmark and this one is the slowest, also has the greatest loss and biggest file size. Sorry,
-
nyholku almost 7 yearsFor HiDPI (Mac retina) displays this creates screenshots at half resolution. To fix that bufferedImage.getGraphics().scale(2, 2) before the argFrame.paint(bufferedImage.getGraphics()) call and use new BufferedImage(rec.width*2, rec.height*2, BufferedImage.TYPE_INT_ARGB) to create the BufferedImage