java getdc_Java – 窗口图像

这个Java程序展示了如何使用GetDC和相关Windows API函数从指定窗口捕获图像,包括创建兼容设备上下文,获取窗口尺寸,以及将位图转换为BufferedImage。
摘要由CSDN通过智能技术生成

这是一个有效的例子.

被捕获的应用程序不能被最小化,但它不需要具有焦点或在顶部(即可见).

相关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);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值