Java - Window Image

Кто-нибудь знает, как сделать снимок экрана на Java (не его собственный экран, а любое другое окно на рабочем столе, и они не обязательно должны быть активное окно) в Windows? На эту похожую тему есть несколько веток, но я еще не нашел ответа.

Я пробовал использовать JNA, но застрял после нескольких попыток. Например ...

public class Main {

    public static void main(String[] args) {
        Main m = new Main();

        List<WindowInfo> list = m.getWindows();

        for (int i=0;i<list.size();i++) 
        {
            WindowInfo info = list.get(i);
            System.out.println(info.getTitle());
        }

        WindowInfo wi = list.get(0);

        W32API.HDC hdcSrc = User32.instance.GetWindowDC(wi.getHwnd());

        W32API.HDC hdcMemory = Gdi32.instance.CreateCompatibleDC(hdcSrc);

        //W32API.HBITMAP hBitmapMemory = Gdi32.instance.CreateCompatibleBitmap(hdcSrc, int width, int height);
        int width = wi.getRect().right - wi.getRect().left;
        int height = wi.getRect().bottom - wi.getRect().top;

        W32API.HBITMAP hBitmapMemory  = Gdi32.instance.CreateCompatibleBitmap(hdcSrc, width, height);

        W32API.HANDLE hOld  = Gdi32.instance.SelectObject(hdcMemory, hBitmapMemory);


        Gdi32.instance.BitBlt(hdcMemory, 0, 0, width, height, hdcSrc, width+2, height+2, 0x00CC0020);


        /* # now how do we convert to a BufferedImage???  */

        // clean up
        Gdi32.instance.SelectObject(hdcMemory, hOld);
        Gdi32.instance.DeleteDC(hdcMemory);
        Gdi32.instance.DeleteObject(hBitmapMemory);
        User32.instance.ReleaseDC(wi.getHwnd(), hdcSrc);


    }


    /**
     *
     * @return
     */
    private List<WindowInfo> getWindows() {

        final List<WindowInfo> list = new ArrayList<WindowInfo>();


        User32.instance.EnumWindows(new WndEnumProc() {
            public boolean callback(int hWnd, int lParam) {
                if (User32.instance.IsWindowVisible(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);
                    if (title!=null&&title.length()>0) {
                        list.add(new WindowInfo(hWnd, r, title));
                    }
                }
                return true;
            }
        }, 0);

        Collections.sort(list, new Comparator<WindowInfo>() {
            public int compare(WindowInfo o1, WindowInfo o2) {
                int i1 = (o1.getTitle()!=null&&o1.getTitle().length()>0?o1.getTitle():" ").charAt(0);
                int i2 = (o2.getTitle()!=null&&o2.getTitle().length()>0?o2.getTitle():" ").charAt(0);
                return i1 - i2;
            }
        });

        return list;
    }
}

Я также пробовал эквивалент API "PrintWindow ()" ...

Graphics g = form.CreateGraphics();
Bitmap bmp = new Bitmap(form.Size.Width, form.Size.Height, g);
Graphics memoryGraphics = Graphics.FromImage(bmp);
IntPtr dc = memoryGraphics.GetHdc();
bool success = PrintWindow(form.Handle, dc, 0);
memoryGraphics.ReleaseHdc(dc);
// bmp now contains the screenshot

Или мне нужно использовать JNI или какой-либо другой инструмент?

7
задан Stefan Freitag 13 March 2018 в 13:53
поделиться