Create a "C:\\CanDelete" directory before running any of this, or change the path building.
Take a screenshot of each monitor individually:
package com.blogspot.whileonefork.screencapture;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class EachMonitor {
public static void main(String[] argv) throws Exception {
//Take a screenshot of every monitor
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] screens = ge.getScreenDevices();
for (GraphicsDevice screen : screens) {
Robot robotForScreen = new Robot(screen);
Rectangle screenBounds = screen.getDefaultConfiguration().getBounds();
//The screen bounds have an annoying tendency to have an offset x/y; we want (0,0) => (width, height)
screenBounds.x = 0;
screenBounds.y = 0;
BufferedImage screenShot = robotForScreen.createScreenCapture(screenBounds);
String ext = "jpg";
String outputFile = "C:\\CanDelete\\screenshot_"
+ screen.getIDstring().replaceAll("[^A-Za-z0-9]", "_")
+ "."
+ ext;
ImageIO.write(screenShot, ext, new File(outputFile));
System.out.println("Saved " + outputFile
+ " of " + screen.getIDstring()
+ " xy=(" + screenBounds.x + "," + screenBounds.y + ")"
+ " bounds=("+ screenBounds.width + "," + screenBounds.height + ")");
}
}
}
Take a single big screenshot of all monitors:
package com.blogspot.whileonefork.screencapture;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class AllMonitors {
public static void main(String[] argv) throws Exception {
/**
* Take one big screenshot of the entire UI.
* On my Windows box monitors seem to act like they are side by side on X, extending on Y.
* Seems, at least on windows, to ignore any offset config setup in display properties.
*/
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);
String ext = "jpg";
String outputFile = "C:\\CanDelete\\AllMonitors"
+ "."
+ ext;
ImageIO.write(screenShot, ext, new File(outputFile));
System.out.println("Saved " + outputFile
+ " of all monitors "
+ " xy=(" + allScreenBounds.x + "," + allScreenBounds.y + ")"
+ " bounds=("+ allScreenBounds.width + "," + allScreenBounds.height + ")");
}
}
All this has been tested exactly once on a Windows box with two monitors of substantially different size; ymmv :)
2 comments:
This seems to give errors when the first monitor is lower than the following monitors. If anyone else runs into this problem a corrected version can be found below. Also note that this version does not save a file, and instead returns a buffered image.
package book;
import java.awt.AWTException;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.util.logging.Level;
import java.util.logging.Logger;
public class AllMonitors {
public BufferedImage getScreenshot() {
//get handle to graphics environment
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] screens = ge.getScreenDevices();
//if screens are detected proceed
if (screens.length > 0) {
try {
//get the first screen
GraphicsDevice a = screens[0];
//get the monitor resolution
Toolkit t = Toolkit.getDefaultToolkit();
Rectangle allScreenBounds = new Rectangle(t.getScreenSize());
//offset screen capture (in cases where first monitor is not the
//highest this will come into effect)
allScreenBounds.y = -1 * screens[0].getDefaultConfiguration().getBounds().y;
//take screenshot
Robot robot = new Robot();
BufferedImage screenShot = robot.createScreenCapture(allScreenBounds);
return screenShot;
} catch (AWTException ex) {
Logger.getLogger(AllMonitors.class.getName()).log(Level.SEVERE, null, ex);
}
}
//if no screens detected return null
return null;
}
}
The code to compute the virtual screen bounds can be found in the jdk's javadoc (http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/GraphicsConfiguration.html):
Rectangle virtualBounds = new Rectangle();
GraphicsEnvironment ge = GraphicsEnvironment.
getLocalGraphicsEnvironment();
GraphicsDevice[] gs =
ge.getScreenDevices();
for (int j = 0; j < gs.length; j++) {
GraphicsDevice gd = gs[j];
GraphicsConfiguration[] gc =
gd.getConfigurations();
for (int i=0; i < gc.length; i++) {
virtualBounds =
virtualBounds.union(gc[i].getBounds());
}
}
Post a Comment