次のようにしてスクリーンショットのバイト配列を取得しています。これは ctypes で行われます。ctypes に問題はありません。これに ctypes タグを付けると、ctypes の人々は混乱するので、すべてのエラー チェックなどを簡略化しました。手順を表示します。
CreateDC('DISPLAY', null, null, null);
nWidth = GetDeviceCaps(hdcScreen, HORZRES); // 1280 // numbers are always divisilbe by 4
nHeight = GetDeviceCaps(hdcScreen, ostypes.CONST.VERTRES); // 1024
nBPP = GetDeviceCaps(hdcScreen, BITSPIXEL); // 32
hdcMemoryDC = ostypes.API('CreateCompatibleDC')(hdcScreen);
bmi = BITMAPV5HEADER();
bmi.bV5Size = BITMAPV5HEADER.size;
bmi.bV5Width = nWidth;
bmi.bV5Height = -1 * nHeight; // top-down
bmi.bV5Planes = 1;
bmi.bV5BitCount = nBPP;
bmi.bV5Compression = BI_BITFIELDS;
bmi.bV5RedMask = 0xff;
bmi.bV5GreenMask = 0xff00;
bmi.bV5BlueMask = 0xff0000;
bmi.bV5AlphaMask = 0xff000000;
cBmi = ctypes.cast(bmi.address(), BITMAPINFO.ptr);
pixelBuffer = BYTE.ptr();
hbmp = CreateDIBSection(hdcScreen, cBmi, DIB_RGB_COLORS, pixelBuffer.address(), null, 0);
SelectObject(hdcMemoryDC, hbmp);
BitBlt(hdcMemoryDC, 0,0, nWidth, nHeight, hdcScreen, 0, 0, SRCCOPY);
byteArr = ctypes.cast(pixelBuffer, BYTE.array(arrLen).ptr).contents;
したがって、上記のフラグを使用すると、次のような BGRA byteArr が得られます。
array(5242880)([240, 200, 105, 255, ..... ])
B は 240、G は 200、R は 105、A は 255 です。
これを RGBA 形式にしたい (ctypes のパフォーマンス上の理由から、C 側で行うことが重要です)。
したがって、これらのマスクを使用して、A が 0 になっても、RGBA 形式に正常に変換できます。
bmi.bV5RedMask = 0xff0000;
bmi.bV5GreenMask = 0xff00;
bmi.bV5BlueMask = 0xff;
bmi.bV5AlphaMask = 0xff000000; // we also tried 0x00000000
これにより、次のことがわかります。
array(5242880)([105, 200, 240, 0, ..... ])
問題は、A 値が 0 になることです。この RGBA 形式を維持しながら、A 値を 255 に維持するにはどうすればよいでしょうか。