Asked  6 Months ago    Answers:  5   Viewed   32 times

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?

 Answers

28

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.

Tuesday, June 1, 2021
 
tompave
answered 6 Months ago
78
try(ImageInputStream in = ImageIO.createImageInputStream(resourceFile)){
    final Iterator<ImageReader> readers = ImageIO.getImageReaders(in);
    if (readers.hasNext()) {
        ImageReader reader = readers.next();
        try {
            reader.setInput(in);
            return new Dimension(reader.getWidth(0), reader.getHeight(0));
        } finally {
            reader.dispose();
        }
    }
} 

Thanks to sfussenegger for the suggestion

Tuesday, June 1, 2021
 
Tapha
answered 6 Months ago
89

You're looking for Graphics.CopyFromScreen. Create a new Bitmap of the right size and pass the Bitmap's Graphics object screen coordinates of the region to copy.

There's also an article describing how to programmatically take snapshots.

Response to edit: I misunderstood what you meant by "desktop". If you want to take a picture of the desktop, you'll have to:

  1. Minimize all windows using the Win32API (send a MIN_ALL message) first
  2. Take the snapshot
  3. Then undo the minimize all (send a MIN_ALL_UNDO message).

A better way to do this would be not to disturb the other windows, but to copy the image directly from the desktop window. GetDesktopWindow in User32 will return a handle to the desktop. Once you have the window handle, get it's device context and copy the image to a new Bitmap.

There's an excellent example on CodeProject of how to copy the image from it. Look for the sample code about getting and creating the device context in the "Capturing the window content" section.

Wednesday, July 28, 2021
 
Saurabh
answered 4 Months ago
18

Try to check the encoding of the JPEG. ImageIO can't read CMYK-encoded jpeg images for example. AFAIK, ImageIO hasn't been updated for years, so you'd like to try and use the official alternative/extension: JAI ImageIO.

Unforutnately, JAI ImageIO needs some native libraries installed into the JRE, which might be unwanted. We do the following:

  • use Apache Sanselan to detect, whether it's a JPEG
  • since Sanselan can't read and write JPEG, use the plain old AWT JPEGCodec: JPEGCodec.createJPEGDecoder(...)
  • to convert CMYK to RGB, we then get the raster of the read BufferedImage and manually convert it (you could use ICC profiles, but the manual conversion fits our needs)

Here's a question of mine that resulted of the fact that ImageIO doesn't support all types of JPEG images, and I there stated a little more of my findings of why you get that message: Pure Java alternative to JAI ImageIO for detecting CMYK images

Sunday, August 1, 2021
 
Maury
answered 4 Months ago
99

You have to use Windows API calls to do this. The following code works in MS Access 2007. It will save BMP files.

Option Compare Database
Option Explicit

Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal _
  bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

Private Const VK_SNAPSHOT = &H2C

Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long

Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Integer) As Long

Private Declare Function CloseClipboard Lib "user32" () As Long

Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" _
(PicDesc As uPicDesc, RefIID As GUID, ByVal fPictureOwnsHandle As Long, _
IPic As IPicture) As Long

'\ Declare a UDT to store a GUID for the IPicture OLE Interface
Private Type GUID
    Data1 As Long
    Data2 As Integer
    Data3 As Integer
    Data4(0 To 7) As Byte
End Type

'\ Declare a UDT to store the bitmap information
Private Type uPicDesc
    Size As Long
    Type As Long
    hPic As Long
    hPal As Long
End Type

Private Const CF_BITMAP = 2
Private Const PICTYPE_BITMAP = 1

Sub PrintScreen()
    keybd_event VK_SNAPSHOT, 1, 0, 0
End Sub

Public Sub MyPrintScreen(FilePathName As String)

    Call PrintScreen

    Dim IID_IDispatch As GUID
    Dim uPicinfo As uPicDesc
    Dim IPic As IPicture
    Dim hPtr As Long

    OpenClipboard 0
    hPtr = GetClipboardData(CF_BITMAP)
    CloseClipboard

    '\ Create the interface GUID for the picture
    With IID_IDispatch
        .Data1 = &H7BF80980
        .Data2 = &HBF32
        .Data3 = &H101A
        .Data4(0) = &H8B
        .Data4(1) = &HBB
        .Data4(2) = &H0
        .Data4(3) = &HAA
        .Data4(4) = &H0
        .Data4(5) = &H30
        .Data4(6) = &HC
        .Data4(7) = &HAB
    End With

    '\ Fill uPicInfo with necessary parts.
    With uPicinfo
        .Size = Len(uPicinfo) '\ Length of structure.
        .Type = PICTYPE_BITMAP '\ Type of Picture
        .hPic = hPtr '\ Handle to image.
        .hPal = 0 '\ Handle to palette (if bitmap).
    End With

   '\ Create the Range Picture Object
   OleCreatePictureIndirect uPicinfo, IID_IDispatch, True, IPic

    '\ Save Picture Object
    stdole.SavePicture IPic, FilePathName

End Sub

There is a Knowledge Base article that goes into more depth.

Tuesday, August 10, 2021
 
MKM
answered 4 Months ago
MKM
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share