问题
I am obtaining a byte array of a screenshot by the following, this is done in ctypes, there is no issues with the ctypes, if I gave this a ctypes tag the ctypes folks would be confused, so I simplified out all the error checking etc to show you the procedure.
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;
So with the above flags I get a BGRA byteArr which looks like this:
array(5242880)([240, 200, 105, 255, ..... ])
So the B is 240, G is 200, R is 105, and A is 255.
I want to get this into a RGBA form (it's important it's done on the C side for ctypes performance reasons).
So now we can successfully get it into RGBA form HOWEVER the A becomes 0, by using these masks:
bmi.bV5RedMask = 0xff0000;
bmi.bV5GreenMask = 0xff00;
bmi.bV5BlueMask = 0xff;
bmi.bV5AlphaMask = 0xff000000; // we also tried 0x00000000
This now gives us:
array(5242880)([105, 200, 240, 0, ..... ])
So the issue is the A value is going to 0, how can I keep this RGBA format, but keep the A value at 255.
回答1:
BitBlt, like nearly all GDI functions, doesn't preserve the alpha values.
If you're blitting from the screen, then all the alphas are 255--the screen doesn't have holes of transparency. So you can just set the alphas yourself after doing the blit.
来源:https://stackoverflow.com/questions/30083256/bitmapv5header-getting-rgba-keep-a-at-255