gpt4 book ai didi

Java - 窗口图像

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:01:44 24 4
gpt4 key购买 nike

有谁知道如何用 Java 捕获屏幕截图(不是它自己的屏幕,而是桌面上的任何其他窗口,它们不一定必须是 Activity 窗口)在 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;
}
}

我也尝试过等效的“PrintWindow()”API...

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 或任何其他工具吗?

最佳答案

这是一个工作示例。

被捕获的应用程序无法最小化,但它不需要具有焦点或位于顶部(即可见)。

相关C#线程中提供的代码,MSDN文章Capturing an Image jmemoryeditorw 提供了必要的部分。

该代码使用GetDC 和GetClientRect 来捕获窗口的客户区。如果您想捕获包括窗口装饰在内的整个窗口,可以将它们替换为 GetWindowDC 和 GetWindowRect。

import java.awt.Graphics;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;

import jna.extra.GDI32Extra;
import jna.extra.User32Extra;
import jna.extra.WinGDIExtra;

import com.sun.jna.Memory;
import com.sun.jna.platform.win32.GDI32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HBITMAP;
import com.sun.jna.platform.win32.WinDef.HDC;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.RECT;
import com.sun.jna.platform.win32.WinGDI;
import com.sun.jna.platform.win32.WinGDI.BITMAPINFO;
import com.sun.jna.platform.win32.WinNT.HANDLE;

public class Paint extends JFrame {

public BufferedImage capture(HWND hWnd) {

HDC hdcWindow = User32.INSTANCE.GetDC(hWnd);
HDC hdcMemDC = GDI32.INSTANCE.CreateCompatibleDC(hdcWindow);

RECT bounds = new RECT();
User32Extra.INSTANCE.GetClientRect(hWnd, bounds);

int width = bounds.right - bounds.left;
int height = bounds.bottom - bounds.top;

HBITMAP hBitmap = GDI32.INSTANCE.CreateCompatibleBitmap(hdcWindow, width, height);

HANDLE hOld = GDI32.INSTANCE.SelectObject(hdcMemDC, hBitmap);
GDI32Extra.INSTANCE.BitBlt(hdcMemDC, 0, 0, width, height, hdcWindow, 0, 0, WinGDIExtra.SRCCOPY);

GDI32.INSTANCE.SelectObject(hdcMemDC, hOld);
GDI32.INSTANCE.DeleteDC(hdcMemDC);

BITMAPINFO bmi = new BITMAPINFO();
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = -height;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = WinGDI.BI_RGB;

Memory buffer = new Memory(width * height * 4);
GDI32.INSTANCE.GetDIBits(hdcWindow, hBitmap, 0, height, buffer, bmi, WinGDI.DIB_RGB_COLORS);

BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
image.setRGB(0, 0, width, height, buffer.getIntArray(0, width * height), 0, width);

GDI32.INSTANCE.DeleteObject(hBitmap);
User32.INSTANCE.ReleaseDC(hWnd, hdcWindow);

return image;

}

public static void main(String[] args) {
new Paint();
}

BufferedImage image;

public Paint() {
HWND hWnd = User32.INSTANCE.FindWindow(null, "Untitled - Notepad");
this.image = capture(hWnd);

setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setExtendedState(MAXIMIZED_BOTH);
setVisible(true);
}

@Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(image, 20, 40, null);
}



}

我必须定义一些没有包含在 platform.jar(可以在 JNA 网站上找到)中的额外函数。

package jna.extra;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.GDI32;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.HDC;
import com.sun.jna.win32.W32APIOptions;

public interface GDI32Extra extends GDI32 {

GDI32Extra INSTANCE = (GDI32Extra) Native.loadLibrary("gdi32", GDI32Extra.class, W32APIOptions.DEFAULT_OPTIONS);

public boolean BitBlt(HDC hObject, int nXDest, int nYDest, int nWidth, int nHeight, HDC hObjectSource, int nXSrc, int nYSrc, DWORD dwRop);

}



package jna.extra;

import com.sun.jna.Native;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HDC;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.RECT;
import com.sun.jna.win32.W32APIOptions;

public interface User32Extra extends User32 {

User32Extra INSTANCE = (User32Extra) Native.loadLibrary("user32", User32Extra.class, W32APIOptions.DEFAULT_OPTIONS);

public HDC GetWindowDC(HWND hWnd);

public boolean GetClientRect(HWND hWnd, RECT rect);

}



package jna.extra;

import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinGDI;

public interface WinGDIExtra extends WinGDI {

public DWORD SRCCOPY = new DWORD(0x00CC0020);

}

关于Java - 窗口图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4433994/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com