用JNI拍摄Windows屏幕截图

时间:2018-02-25 01:33:12

标签: c windows java-native-interface

我正试图在Windows上使用JNI本地截取屏幕截图,但我似乎无法做到这一点。部分是因为我不完全理解这是如何工作的。我已经掌握了JNI的知识,但我不能让这个截图工作。我到了我有一个HBITMAP并且我调用了GetDIBits,但我不明白为什么我需要调用它,为什么它不起作用。如果有人可以帮助我,我真的很感激!

HDC hScreenDC = CreateDC(L"DISPLAY", NULL, NULL, NULL);
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);

int width = GetDeviceCaps(hScreenDC, HORZRES);
int height = GetDeviceCaps(hScreenDC, VERTRES);

int size = height * (width * 3);

printf("Width: %d, height: %d, size: %d", width, height, size);

if (width <= 0 && height <= 0) {
    return NULL;
}

HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);

BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);
hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap);

BITMAPINFO bmi;
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = height;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = 0;
bmi.bmiHeader.biSizeImage = size;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;

char* scanlines = new char[size];

bool result = GetDIBits(hMemoryDC, hBitmap, 0, height, scanlines, &bmi, DIB_RGB_COLORS);

if (!result) {
    printf("GetDIBits failed!");
    return NULL;
}

DeleteDC(hScreenDC);
DeleteDC(hMemoryDC);

jbyteArray returnArray = env->NewByteArray(size);
jbyte* jBytes = env->GetByteArrayElements(returnArray, FALSE);

for (int i = 0; i < sizeof(scanlines); i++) {
    jBytes[i] = scanlines[i];
}

env->SetByteArrayRegion(returnArray, 0, size, jBytes);

return returnArray;

1 个答案:

答案 0 :(得分:0)

你最大的明显问题,就是看一下代码,就是在一个指针上调用sizeof,它会让你回到4位,总是在32位,所以你实际上只使用前4行。

更正确的是:

for (int i = 0; i < size; i++) {
    jBytes[i] = scanlines[i];
}