Compile a JavaRobot-based screen capture tool

Source: Internet
Author: User
Tags gety home screen
Compile a JavaRobot-based screen capture tool-general Linux technology-Linux programming and kernel information. The following is a detailed description. Java Fun and Games (Java entertainment and Games) provides the ability to capture the home screen device through the Java Robot class, and can save the entire screen or selected part as a jpeg file. This article provides a screen capture tool in the form of a Swing application.

Java Fun and Games (Java entertainment and Games) provides the ability to capture the home screen device through the Java Robot class, and can save the entire screen or selected part as a jpeg file.

Note: Now you can use the online development tool DevSquare to compile and run the applet provided in Java Fun and Games. For more information about DevSquare, see the User Guide provided in the resource.

The java. awt. Robot class provides some useful methods for entertainment functions. One of them includes the function of creating a screen capture tool. Java Fun and Games provides a tool that uses Robot to capture the content of the home screen device.

This part is separated from my previous parts because it is not concentrated on the applet implementation. This article provides a screen capture tool in the form of a Swing application. After introducing this application from the GUI point of view, I will explain the key part of the implementation.

Copyright Disclaimer: Any website authorized by Matrix must retain the following author information and links for reprinting.
Author: Jeff Friesen; mydeman
Original article: http://www.javaworld.com/javaworld/jw-04-2006/jw-0424-funandgames.html
Matrix: http://www.matrix.org.cn/resource/article/2006-09-15/Java+Robot_f9598e5e-445b-11db-af0b-0f766c077b58.html
Keywords: Java Robot; capture screen

Application GUI
My Capture program provides a graphical User Interface (GUI, Graphic User Interface) through which you can choose to Capture part of the image, trim the image to the selected content, and save the result image as a jpeg file. Displays the Capture GUI that contains a Capture example.



(400) {this. resized = true; this. width = 400; this. alt = 'click here to open new window';} "onmouseover =" if (this. resized) this. style. cursor = 'hand'; "onclick =" window. open ('HTTP: // java.ccidnet.com/col/attachment/2006/10/855741.gif'); ">
Figure 1. The rectangle formed by the red and white dotted lines represents the selected area

The Capture GUI consists of a menu bar and a scrollable window for displaying captured images. 1. Select a rectangle (drag the mouse) to capture a rectangular area of the image.

The menu bar provides the File and Capture menus:
--- File provides Save... You can use the File selector to save the current Capture as a jpeg file and Exit the Capture. Although you can directly select these menu items, you will find it easier to use their Shortcut Keys Alt-S and Alt-X.
--- Capture provides the Capture (Capture) and Crop (TRIM) menu items to Capture the content of the current home screen device and trim an image as the content of the selected rectangle. Like File menu items, these menu items also have their own convenient Shortcut Keys: Capture (Alt-C) and Crop (Alt-K ).

Application Implementation

There are three source files to describe the Capture GUI: Capture. java (start the application and construct the GUI), ImageArea. java (describes a component used to display captured content, you can also select a part of the captured content or trim the captured content) and ImageFileFilter. java (restrict the selection of file selectors to folders and jpeg files ). Below, I have extracted some code snippets from these source files to illustrate the working process of Capture.

Robot screen capture
To Capture the screen using the Robot class, Capture must first create a Robot object. The public static void main (String [] args) method of the Capture class tries to call the public Robot () constructor of the Robot to create this object. If it is successfully created, a Robot reference to the coordinate system of the home screen device is returned. If the platform does not support low-level control (this is true in environments without screen devices), java. awt. AWTException will be thrown. If the platform does not allow the creation of a Robot object, java. lang. SecurityException is thrown. I hope you will not encounter any other exceptions.

Assuming that the Robot object has been created, main () calls the constructor of the Capture class to create a GUI. As part of the GUI creation, Capture obtains the size of the home screen device by calling dimScreenSize = Toolkit. getDefaultToolkit (). getScreenSize. Because the public BufferedImage createScreenCapture (Rectangle screenRect) method of the Robot used to display the captured content on the screen requires a java. awt. the Rectangle parameter, so the constructor uses rectScreenSize = new Rectangle (dimScreenSize. awt. the Dimension object is converted into a Rectangle object. When the action listener of the Capture menu item is called, The following excerpt of Capture. java will call createScreenCapture (). // Hide Capture's main window so that it does not appear in
// The screen capture.

SetVisible (false );

// Perform the screen capture.

BufferedImage biScreen;
BiScreen = robot. createScreenCapture (rectScreenSize );

// Show Capture's main window for continued user interaction.

SetVisible (true );

// Update ImageArea component with the new image and adjust
// The scrollbars.

Ia. setImage (biScreen );

Jsp. getHorizontalScrollBar (). setValue (0 );
Jsp. getVerticalScrollBar (). setValue (0 );

You do not want the Capture GUI to cover anything you want to Capture. This is why the priority of hiding the Capture GUI in the Code is higher than that of completing the Capture. After obtaining the java. awt. image. BufferedImage that contains the screen pixel copy, the code snippet shows the GUI and the BufferedImage content is displayed through the image area component.

Sub-Image Selection
When obtaining a sub-image from a captured image, a selection rectangle is required. The ImageArea class provides code to create, operate, and draw selection rectangles. As shown in the following excerpt ImageArea. java shows that the constructor of this class creates a selection Rectangle with a Rectangle instance and creates a java. awt. basicStoke and java. awt. the GradientPaint object defines the profile appearance of a rectangle (keep it separate from the underlying image). Registering a mouse and Mouse Action listener allows you to operate and select a rectangle. // Create a selection Rectangle. It's better to create o-ne Rectangle
// Here than a Rectangle each time paintComponent () is called, to reduce
// Unnecessary object creation.

RectSelection = new Rectangle ();

// Define the stroke for drawing selection rectangle outline.

Bs = new BasicStroke (5, BasicStroke. CAP_ROUND, BasicStroke. JOIN_ROUND,
0, new float [] {12, 12}, 0 );

// Define the gradient paint for coloring selection rectangle outline.

Gp = new GradientPaint (0.0f, 0.0f, Color. red, 1.0f, 1.0f, Color. white,
True );

// Install a mouse listener that sets things up for a selection drag.

MouseListener ml;
Ml = new MouseAdapter ()
{
Public void mousePressed (MouseEvent e)
{
// When you start Capture, there is no captured image.
// Therefore, it makes no sense to try and select a sub-image.
// This is the reason for the if (image = null) test.

If (image = null)
Return;

Destx = srcx = e. getX ();
Desty = srcy = e. getY ();

Repaint ();
}
};
AddMouseListener (ml );

// Install a mouse motion listener to update the selection rectangle
// During drag operations.

MouseMotionListener mml;
Mml = new MouseMotionAdapter ()
{
Public void mouseDragged (MouseEvent e)
{
// When you start Capture, there is no captured image.
// Therefore, it makes no sense to try and select
// Sub-image. This is the reason for the if (image = null)
// Test.

If (image = null)
Return;

Destx = e. getX ();
Desty = e. getY ();

Repaint ();
}
};
AddMouseMotionListener (mml );

When you press the mouse, the mouse event processor sets destx and srcx for the same horizontal mouse coordinates, as well as for vertical mouse coordinates. The source and target variables also indicate which display selection rectangles should be removed. By calling repaint (), the public void paintComponent (Graphics g) is called. This method compares srcx and srcy with destx and desty respectively. if they are different, Draw a selection rectangle: // Draw the selection rectangle if present.

If (srcx! = Destx | srcy! = Desty)
{
// Compute upper-left and lower-right coordinates for selection
// Rectangle corners.

Int x1 = (srcx destx )? Srcx: destx;
Int y2 = (srcy> desty )? Srcy: desty;

// Establish selection rectangle origin.

RectSelection. x = x1;
RectSelection. y = y1;

// Establish selection rectangle extents.

RectSelection. width = (x2-x1) + 1;
RectSelection. height = (y2-y1) + 1;

// Draw selection rectangle.

Graphics2D g2d = (Graphics2D) g;
G2d. setStroke (bs );
G2d. setPaint (gp );
G2d. draw (rectSelection );
}

Before you draw a rectangle, it must be marked on the left and right corners to determine the origin and range of the rectangle. So that you can drag a selection rectangle (such as the bottom right or top left) in different directions. The minimum values of srcx/destx and srcy/desty indicate the upper left corner. Similarly, their maximum values represent the lower right corner.

Image trim
After selecting a sub-image, you want to trim the captured image to obtain the sub-image. Image trim starts the action listener for the menu item in Crop, which requests ImageArea to trim the captured image as the selected sub-image. If the operation result is displayed, the listener resets the scroll bar of ImageArea. Otherwise, the listener provides an "Out of bounds" error message in the dialog box. // Crop ImageArea component and adjust the scrollbars if
// Cropping succeeds.

If (ia. crop ())
{
Jsp. getHorizontalScrollBar (). setValue (0 );
Jsp. getVerticalScrollBar (). setValue (0 );
}
Else
ShowError ("Out of bounds .");

Because the trim operation does not reset the size of the Capture GUI, you can view the background and result image of the main window (after initial trim) at the same time ). When a part of the selected image is displayed, it is also possible to select a part of the background.



(400) {this. resized = true; this. width = 400; this. alt = 'click here to open new window';} "onmouseover =" if (this. resized) this. style. cursor = 'hand'; "onclick =" window. open ('HTTP: // java.ccidnet.com/col/attachment/2006/10/855743.gif'); ">
Figure 2. Try to select more than this image

The background pixels of the main window are not part of the captured image; they cannot be included in the trimmed image. Therefore, the operation fails whenever the background pixel is included in the trim area, and an "Out of bounds" error message is displayed.

The TRIM operation is handled by the public Boolean crop () method of ImageArea. If the trim is completed or the sub-image is not selected (it is very convenient to call this method when no content is selected) This method (as shown below) returns true. If the selected area contains background pixels, false is returned. Public boolean crop ()
{
// There is nothing to crop if the selection rectangle is o ly nly a single
// Point.

If (srcx = destx & srcy = desty)
Return true;

// Assume success.

Boolean succeeded = true;

// Compute upper-left and lower-right coordinates for selection rectangle
// Corners.

Int x1 = (srcx destx )? Srcx: destx;
Int y2 = (srcy> desty )? Srcy: desty;

// Compute width and height of selection rectangle.

Int width = (x2-x1) + 1;
Int height = (y2-y1) + 1;

// Create a buffer to hold cropped image.

BufferedImage biCrop = new BufferedImage (width, height,
BufferedImage. TYPE_INT_RGB );
Graphics2D g2d = biCrop. createGraphics ();

// Perform the crop operation.

Try
{
BufferedImage bi = (BufferedImage) image;
BufferedImage bi2 = bi. getSubimage (x1, y1, width, height );
G2d. drawImage (bi2, null, 0, 0 );
}
Catch (RasterFormatException e)
{
Succeeded = false;
}

G2d. dispose ();

If (succeeded)
SetImage (biCrop); // Implicitly remove selection rectangle.
Else
{
// Prepare to remove selection rectangle.

Srcx = destx;
Srcy = desty;

// Explicitly remove selection rectangle.

Repaint ();
}

Return succeeded;
}

The crop () method calls the public BufferedImage getSubimage (int x, int y, int w, int h) method of BufferedImage to extract sub-images in the selection area. If the image in BufferedImage is not specified in the parameter of this method, it throws a java. awt. image. RasterFormatException, and false is returned.

Image Storage
Capture allows you to save the captured image as a jpeg file. You specify the file name through a save file selector, which is created by the constructor of the Capture class: // Construct a save file-chooser. Initialize the starting directory
// The current directory, do not allow the user to select the "all files"
// Filter, and restrict the files that can be selected to those ending
// With. jpg or. jpeg extensions.

Final JFileChooser fcSave = new JFileChooser ();
FcSave. setCurrentDirectory (new File (System. getProperty ("user. dir ")));
FcSave. setAcceptAllFileFilterUsed (false );
FcSave. setFileFilter (new ImageFileFilter ());

To restrict the file selector from selecting a file whose folder is suffixed with .jpg or .jpeg, an instance of the ImageFileFilter class is used as the file filter for the file selector during storage. False: public boolean accept (File f) is returned for any File folder with a suffix other than .jpg/. jpeg)
{
// Allow the user to select directories so that the user can navigate
// File system.

If (f. isDirectory ())
Return true;

// Allow the user to select files ending with a. jpg or a. jpeg
// Extension.

String s = f. getName ();
Int I = s. lastIndexOf ('.');

If (I> 0 & I

When you select Save... The listener displays a save file selector. If you do not exit the selector, the monitor will ensure that the selected file name is a suffix of .jpg or .jpeg. The listener will determine whether the file exists, so that you will not overwrite an existing file. // Present the "save" file-chooser without any file selected.
// If the user cancels this file-chooser, exit this method.

FcSave. setSelectedFile (null );
If (fcSave. showSaveDialog (Capture. this )! =
JFileChooser. APPROVE_OPTION)
Return;

// Obtain the selected file. Validate its extension, which
// Must be. jpg or. jpeg. If extension not present, append
//. Jpg extension.

File file = fcSave. getSelectedFile ();
String path = file. getAbsolutePath (). toLowerCase ();
If (! Path. endsWith (". jpg ")&&! Path. endsWith (". jpeg "))
File = new File (path + = ". jpg ");

// If the file exists, inform the user, who might not want
// To accidentally overwrite an existing file. Exit method
// If the user specifies that it is not okay to overwrite
// The file.

If (file. exists ())
{
Int choice = JOptionPane.
ShowConfirmDialog (null,
"Overwrite file? ",
"Capture ",
JOptionPane.
YES_NO_OPTION );
If (choice = JOptionPane. NO_OPTION)
Return;
}

If the file does not exist or you are allowed to overwrite the existing file, the listener will save the captured content as a selected file. To complete this task, the listener uses the Java ImageIO Framework to select a jpeg writer, specify the file as the writer target, set the compression quality of the writer to 95%, and then write the image to the file. ImageWriter writer = null;
ImageOutputStream ios = null;

Try
{
// Obtain a writer based o ­ n the jpeg format.

Iterator iter;
Iter = ImageIO. getImageWritersByFormatName ("jpeg ");

// Validate existence of writer.

If (! Iter. hasNext ())
{
ShowError ("Unable to save image to jpeg file type .");
Return;
}

// Extract writer.

Writer = (ImageWriter) iter. next ();

// Configure writer output destination.

Ios = ImageIO. createImageOutputStream (file );
Writer. setOutput (ios );

// Set jpeg compression quality to 95%.

ImageWriteParam iwp = writer. getDefaultWriteParam ();
Iwp. setCompressionMode (ImageWriteParam. MODE_EXPLICIT );
Iwp. setCompressionQuality (0.95f );

// Write the image.

Writer. write (null,
New IIOImage (BufferedImage)
Ia. getImage (), null, null ),
Iwp );
}
Catch (IOException e2)
{
ShowError (e2.getMessage ());
}
Finally
{
Try
{
// Cleanup.

If (ios! = Null)
{
Ios. flush ();
Ios. close ();
}

If (writer! = Null)
Writer. dispose ();
}
Catch (IOException e2)
{
}
}

It has always been a good idea to clear the code yourself. I put the ImageIO cleanup code in the finally clause, so that it can be executed whether it ends normally or throws an exception.

Summary

Capture limits that captured content can only be captured on the home screen device. You may want to enhance Capture to Capture the content of all additional screen devices (perhaps a huge virtual screen. One enhancement, You need to include the following code, which captures the content of all the screens and integrates it with the existing Code of Capture. java. GraphicsEnvironment graphenv = GraphicsEnvironment. getLocalGraphicsEnvironment ();
GraphicsDevice [] screens = graphenv. getScreenDevices ();
BufferedImage [] captures = new BufferedImage [screens. length];

For (int I = 0; I

Place the above Code in the Action listener of the Capture menu item. Then introduce the code to create a large enough BufferedImage to be referenced by bigScreen, which can save all the BufferedImage content referenced by the captures array; then introduce the code to draw them into bigScreen. Capture is now a single screen catcher.

About the author
Jeff Friesen is a free software developer and educator, especially in the C, C ++, and Java fields.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.