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?
-
2Thanks to this question, I wrote a tutorial for absolute beginners on my blog: http://www.thepcwizard.in/2012/12/java-screen-capturing-tutorial.html – ThePCWizard Dec 24 '12 at 08:59
-
http://web.archive.org/web/20090204074007/http://schmidt.devlib.org/java/save-screenshot.html – John Millikin Sep 12 '08 at 04:39
-
@ThePCWizard the link is not working – rajeev pani.. Apr 13 '22 at 11:03
-
@rajeevpani.. Article moved here: https://blog.vidursoft.com/2012/12/java-screen-capturing-tutorial.html – ThePCWizard Apr 16 '22 at 07:01
8 Answers
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.

- 136,852
- 53
- 295
- 323

- 43,219
- 21
- 62
- 72
-
1I wonder if this is what screen sharing applications like Elluminate (http://www.elluminate.com/) use. – Chris Wagner Apr 22 '10 at 22:25
-
@java_enthu actually yes, it will be work without console if you will hardcode path to screenshot in your app. – Dmitry Zagorulkin Aug 27 '12 at 13:56
-
2Robot 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? – nullUser Jun 27 '13 at 15:14
-
3
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();
}
}

- 1,560
- 1
- 15
- 27

- 18,787
- 4
- 46
- 77
-
18
-
2
-
3It looks like this should have the advantage of working even if the target window is obscured before the screenshot is taken. – Brad Mace Jul 28 '14 at 14:33
-
8On the other hand, this gets only the contents of the window, whereas with `Robot` you can also get the window's frame and titlebar. – Brad Mace Jul 28 '14 at 15:57
-
@BradMace: that is a good point. I did not need the frame and titlebar, just the content... – DejanLekic Apr 08 '16 at 08:25
-
1For 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 – nyholku Aug 04 '17 at 06:44
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);

- 7,679
- 2
- 42
- 52
-
5would be better to calculate it [this way](http://stackoverflow.com/a/13380999/446591) – Brad Mace Jul 15 '14 at 19:39
-
@BradMace That answer solved my problem, thank you for linking it here! – Brian_Entei Nov 19 '22 at 03:16
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));
}

- 136,852
- 53
- 295
- 323

- 143
- 2
- 7
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;
public class HelloWorldFrame extends JFrame implements ActionListener {
JButton b;
public HelloWorldFrame() {
this.setVisible(true);
this.setLayout(null);
b = new JButton("Click Here");
b.setBounds(380, 290, 120, 60);
b.setBackground(Color.red);
b.setVisible(true);
b.addActionListener(this);
add(b);
setSize(1000, 700);
}
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == b)
{
this.dispose();
try {
Thread.sleep(1000);
Toolkit tk = Toolkit.getDefaultToolkit();
Dimension d = tk.getScreenSize();
Rectangle rec = new Rectangle(0, 0, d.width, d.height);
Robot ro = new Robot();
BufferedImage img = ro.createScreenCapture(rec);
File f = new File("myimage.jpg");//set appropriate path
ImageIO.write(img, "jpg", f);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
public static void main(String[] args) {
HelloWorldFrame obj = new HelloWorldFrame();
}
}

- 890
- 9
- 8
-
I did a benchmark and this one is the slowest, also has the greatest loss and biggest file size. Sorry, – Liam Larsen Jul 01 '17 at 08:47
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

- 390
- 2
- 12
You can use java.awt.Robot
to achieve this task.
below is the code of server, which saves the captured screenshot as image in your Directory.
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.imageio.ImageIO;
public class ServerApp extends Thread
{
private ServerSocket serverSocket=null;
private static Socket server = null;
private Date date = null;
private static final String DIR_NAME = "screenshots";
public ServerApp() throws IOException, ClassNotFoundException, Exception{
serverSocket = new ServerSocket(61000);
serverSocket.setSoTimeout(180000);
}
public void run()
{
while(true)
{
try
{
server = serverSocket.accept();
date = new Date();
DateFormat dateFormat = new SimpleDateFormat("_yyMMdd_HHmmss");
String fileName = server.getInetAddress().getHostName().replace(".", "-");
System.out.println(fileName);
BufferedImage img=ImageIO.read(ImageIO.createImageInputStream(server.getInputStream()));
ImageIO.write(img, "png", new File("D:\\screenshots\\"+fileName+dateFormat.format(date)+".png"));
System.out.println("Image received!!!!");
//lblimg.setIcon(img);
}
catch(SocketTimeoutException st)
{
System.out.println("Socket timed out!"+st.toString());
//createLogFile("[stocktimeoutexception]"+stExp.getMessage());
break;
}
catch(IOException e)
{
e.printStackTrace();
break;
}
catch(Exception ex)
{
System.out.println(ex);
}
}
}
public static void main(String [] args) throws IOException, SQLException, ClassNotFoundException, Exception{
ServerApp serverApp = new ServerApp();
serverApp.createDirectory(DIR_NAME);
Thread thread = new Thread(serverApp);
thread.start();
}
private void createDirectory(String dirName) {
File newDir = new File("D:\\"+dirName);
if(!newDir.exists()){
boolean isCreated = newDir.mkdir();
}
}
}
And this is Client code which is running on thread and after some minutes it is capturing the screenshot of user screen.
package com.viremp.client;
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.Socket;
import java.util.Random;
import javax.imageio.ImageIO;
public class ClientApp implements Runnable {
private static long nextTime = 0;
private static ClientApp clientApp = null;
private String serverName = "192.168.100.18"; //loop back ip
private int portNo = 61000;
//private Socket serverSocket = null;
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
clientApp = new ClientApp();
clientApp.getNextFreq();
Thread thread = new Thread(clientApp);
thread.start();
}
private void getNextFreq() {
long currentTime = System.currentTimeMillis();
Random random = new Random();
long value = random.nextInt(180000); //1800000
nextTime = currentTime + value;
//return currentTime+value;
}
@Override
public void run() {
while(true){
if(nextTime < System.currentTimeMillis()){
System.out.println(" get screen shot ");
try {
clientApp.sendScreen();
clientApp.getNextFreq();
} catch (AWTException e) {
// TODO Auto-generated catch block
System.out.println(" err"+e);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch(Exception e){
e.printStackTrace();
}
}
//System.out.println(" statrted ....");
}
}
private void sendScreen()throws AWTException, IOException {
Socket serverSocket = new Socket(serverName, portNo);
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension dimensions = toolkit.getScreenSize();
Robot robot = new Robot(); // Robot class
BufferedImage screenshot = robot.createScreenCapture(new Rectangle(dimensions));
ImageIO.write(screenshot,"png",serverSocket.getOutputStream());
serverSocket.close();
}
}

- 424
- 1
- 3
- 19
Toolkit returns pixels based on PPI, as a result, a screenshot is not created for the entire screen when using PPI> 100% in Windows. I propose to do this:
DisplayMode displayMode = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getDisplayMode();
Rectangle screenRectangle = new Rectangle(displayMode.getWidth(), displayMode.getHeight());
BufferedImage screenShot = new Robot().createScreenCapture(screenRectangle);

- 74
- 3