How to capture selected screen of other applicatio

2019-02-03 12:11发布

We are trying to develop a screen capture utility.

How do we capture selected screen of another application using Java? And how do we add a callout to the captured screen?

8条回答
Emotional °昔
2楼-- · 2019-02-03 12:51

Perhaps the java.awt.Robot class would help with the screen shots, although I do not think it is capable of locating individual windows. As for these "call outs", the Robot class can also invoke mouse clicks and key presses, if that is what you mean.

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-02-03 12:57

Based on Prajakta's description of the project, I believe some explanation of manipulating a screen shot is in order (I think John did an excellent job of explaining how to capture the screen shot using the java.awt.Robot class). Remember, as Steve McLeod said, Java may not be able to automatically locate the location of the window you want to capture on the screen. This is important, because the Robot class needs to know this location, either automatically or manually from you.

Callouts, text, images, etc can be added to the screen shot via the Graphics2D object you receive when you call the createGraphics() method of the screen shot's BufferedImage. I highly recommend you check out the Graphics2D's API to better understand what it is capable of. I also recommend finding some tutorials, perhaps starting with the the 2D Graphics Tutorial from Sun. The book entitled "Filthy Rich Clients" may also come in useful.

When you finally want to save this modified screen shot, you can use the one of the "write" methods of the ImageIO class.

Here is a very simple, start-to-finish example. It is up to you to fill in whatever details necessary.

I hope this help a little!

Robot robot = new Robot();

// The hard part is knowing WHERE to capture the screen shot from
BufferedImage screenShot = robot.createScreenCapture(x, y, width, height);
Graphics2D graphics = screenShot.createGraphics();

// Add a label to the screen shot
Color textColor = Color.RED;
graphics.setColor(textColor);
graphics.drawString("Some text", textX, textY);

// Save your screen shot with its label
ImageIO.save(screenShot, "png", new File("myScreenShot.png"));
查看更多
Ridiculous、
4楼-- · 2019-02-03 12:59

You will need to provide more specific information in order to receive meaningful help. To start with, Which operating systems does this need to work on? Do you need to capture the contents of individual windows or literally entire displays (you used the ambiguous term "selected screen of other application" in your original post). What specifically do you want to see when you "add callout to captured screen"?

查看更多
▲ chillily
5楼-- · 2019-02-03 13:06

With this code i could make screens of certain windows in windows10, dont forget the dependency.

Credits go to: Windows: how to get a list of all visible windows?

<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>4.5.0</version>
</dependency>

Code:

import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.imageio.ImageIO;

import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.win32.StdCallLibrary;

public class Main {
    public static void main(String[] args) throws AWTException, IOException {

        int hWnd = User32.instance.FindWindowA(null, "Minesweeper X");
        WindowInfo w = getWindowInfo(hWnd);
        User32.instance.SetForegroundWindow(w.hwnd);
        BufferedImage createScreenCapture = new Robot().createScreenCapture(new Rectangle(w.rect.left, w.rect.top, w.rect.right - w.rect.left, w.rect.bottom - w.rect.top));
        ImageIO.write(createScreenCapture, "png", new File("screen.png"));

        // listAllWindows();
    }

    private static void listAllWindows() throws AWTException, IOException {
        final List<WindowInfo> inflList = new ArrayList<WindowInfo>();
        final List<Integer> order = new ArrayList<Integer>();
        int top = User32.instance.GetTopWindow(0);
        while (top != 0) {
            order.add(top);
            top = User32.instance.GetWindow(top, User32.GW_HWNDNEXT);
        }

        User32.instance.EnumWindows(new WndEnumProc() {
            public boolean callback(int hWnd, int lParam) {
                WindowInfo info = getWindowInfo(hWnd);
                inflList.add(info);
                return true;
            }

        }, 0);
        Collections.sort(inflList, new Comparator<WindowInfo>() {
            public int compare(WindowInfo o1, WindowInfo o2) {
                return order.indexOf(o1.hwnd) - order.indexOf(o2.hwnd);
            }
        });
        for (WindowInfo w : inflList) {
            System.out.println(w);
        }
    }

    public static  WindowInfo getWindowInfo(int hWnd) {
        RECT r = new RECT();
        User32.instance.GetWindowRect(hWnd, r);
        byte[] buffer = new byte[1024];
        User32.instance.GetWindowTextA(hWnd, buffer, buffer.length);
        String title = Native.toString(buffer);
        WindowInfo info = new WindowInfo(hWnd, r, title);
        return info;
    }

    public static interface WndEnumProc extends StdCallLibrary.StdCallCallback {
        boolean callback(int hWnd, int lParam);
    }

    public static interface User32 extends StdCallLibrary {
        public static final String SHELL_TRAY_WND = "Shell_TrayWnd";
        public static final int WM_COMMAND = 0x111;
        public static final int MIN_ALL = 0x1a3;
        public static final int MIN_ALL_UNDO = 0x1a0;

        final User32 instance = (User32) Native.loadLibrary("user32", User32.class);

        boolean EnumWindows(WndEnumProc wndenumproc, int lParam);

        boolean IsWindowVisible(int hWnd);

        int GetWindowRect(int hWnd, RECT r);

        void GetWindowTextA(int hWnd, byte[] buffer, int buflen);

        int GetTopWindow(int hWnd);

        int GetWindow(int hWnd, int flag);

        boolean ShowWindow(int hWnd);

        boolean BringWindowToTop(int hWnd);

        int GetActiveWindow();

        boolean SetForegroundWindow(int hWnd);

        int FindWindowA(String winClass, String title);

        long SendMessageA(int hWnd, int msg, int num1, int num2);

        final int GW_HWNDNEXT = 2;
    }

    public static class RECT extends Structure {
        public int left, top, right, bottom;

        @Override
        protected List<String> getFieldOrder() {
            List<String> order = new ArrayList<>();
            order.add("left");
            order.add("top");
            order.add("right");
            order.add("bottom");
            return order;
        }
    }

    public static class WindowInfo {
        int hwnd;
        RECT rect;
        String title;

        public WindowInfo(int hwnd, RECT rect, String title) {
            this.hwnd = hwnd;
            this.rect = rect;
            this.title = title;
        }

        public String toString() {
            return String.format("(%d,%d)-(%d,%d) : \"%s\"", rect.left, rect.top, rect.right, rect.bottom, title);
        }
    }
}
查看更多
萌系小妹纸
6楼-- · 2019-02-03 13:10
Robot r = new Robot();
Toolkit t = Toolkit.getDefaultToolkit();
Dimension d = t.getScreenSize();
Image i = r.createScreenCapture( 0, 0, d.width, d.height );

should get you a whole image of the whole screen. not sure if that gets you the whole things if you have multiple monitors, though...

查看更多
\"骚年 ilove
7楼-- · 2019-02-03 13:12
登录 后发表回答