如果我的窗口处于32位色深模式,那么下面的代码将从窗口中获取漂亮的PIL图像:
def image_grab_native(window):
hwnd = win32gui.GetDesktopWindow()
left, top, right, bot = get_rect(window)
w = right - left
h = bot - top
hwndDC = win32gui.GetWindowDC(hwnd)
mfcDC = win32ui.CreateDCFromHandle(hwndDC)
saveDC = mfcDC.CreateCompatibleDC()
saveBitMap = win32ui.CreateBitmap()
saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)
saveDC.SelectObject(saveBitMap)
saveDC.BitBlt((0, 0), (w, h), mfcDC, (left, top), win32con.SRCCOPY)
bmpinfo = saveBitMap.GetInfo()
bmpstr = saveBitMap.GetBitmapBits(True)
im = Image.frombuffer(
'RGB',
(bmpinfo['bmWidth'], bmpinfo['bmHeight']),
bmpstr, 'raw', 'BGRX', 0, 1)
win32gui.DeleteObject(saveBitMap.GetHandle())
saveDC.DeleteDC()
mfcDC.DeleteDC()
win32gui.ReleaseDC(hwnd, hwndDC)
return im
但是,以16位模式运行时,出现错误:
>>> image_grab_native(win)
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
image_grab_native(win)
File "C:\claudiu\bumhunter\finderbot\ezpoker\utils\win32.py", line 204, in image_grab_native
bmpstr, 'raw', 'BGRX', 0, 1)
File "c:\python25\lib\site-packages\PIL\Image.py", line 1808, in frombuffer
return apply(fromstring, (mode, size, data, decoder_name, args))
File "c:\python25\lib\site-packages\PIL\Image.py", line 1747, in fromstring
im.fromstring(data, decoder_name, args)
File "c:\python25\lib\site-packages\PIL\Image.py", line 575, in fromstring
raise ValueError("not enough image data")
ValueError: not enough image data
我应该如何形成frombuffer
以16位模式工作的电话?另外,如何使该函数在任何位深度模式下都能工作,而不必说必须将其作为参数传递呢?
更新:从这个问题中,我了解到我必须对第二个模式参数使用“ BGR; 16”而不是“
BGRX”。它可以拍出正确的照片,无论是否指定步幅。问题是像素值在某些值上略有偏离:
x y native ImageGrab
280 0 (213, 210, 205) (214, 211, 206)
280 20 (156, 153, 156) (156, 154, 156)
280 40 (213, 210, 205) (214, 211, 206)
300 0 (213, 210, 205) (214, 211, 206)
只是从同一窗口获取的值样本。屏幕截图看起来和肉眼是一样的,但是我必须做一些像素操作。.我也想完全使用本机方法的原因是它速度更快,并且在带有双监视器的虚拟机中运行时表现更好。
(是的,我知道是非常随机的复杂问题)。
对于stride
参数,您需要提供以字节为单位的行大小。您的像素均为16位,因此您可能会天真地假设stride = 2*bmpinfo['bmWidth']
;不幸的是,Windows添加了填充以使步幅达到32位的偶数倍。这意味着您必须将其舍入到4的下一个最高倍数stride = (stride + 3) / 4) * 4
。
该文档没有提到16位原始格式,因此您必须检查Unpack.c模块以查看可用的格式。
您会注意到的最后一件事是Windows喜欢将其位图倒置。
编辑:
您最后的小问题很容易解释-从16位到24位的转换没有精确定义,并且两次不同转换之间的一对一差异是完全正常的。转换完数据后,调整数据并不难,因为我确信差异基于值是恒定的。
我得到了一个字节数组,存储了一个已经解构的DICOM文件中的16位像素数据。我现在需要做的是以某种方式将像素数据转换/导出为TIFF文件格式。我使用imageio-tiff-3.3.2.jar插件来处理tiff转换/头数据。但是现在我需要将该图像数据数组打包到原始图像维度的BufferedImage中,以便将其导出到TIFF。但是BufferedImage似乎不支持16位图像。有没有办法解决这个问
当我以tiff格式打开一个16位图像时,它会以黑色图像的形式打开。16位tiff图像仅在程序ImageJ中打开;但是,它不会在预览中打开。我想知道我现在的选择是什么,以一种不降低分辨率的更简单的方式查看格式,而不是打开ImageJ查看它。我是否应该将其转换为8位格式,但当格式从16位减少到8位时,是否会丢失数据?另外,我正在考虑将tiff图像转换为jpeg,但这会导致分辨率降低吗?
我是第一次使用openCV。我正在使用openCV3和XCode对其进行编码。我想创建一个16位的灰度图像,但我想我有的数据是这样定义的,4000是像素值为白色和0为黑色。我在int类型的数组中有这些像素的信息。如何创建Mat并将数组中的值分配给Mat?
我想提取一个BufferedImage的矩形。 Javadoc提出了getSubImage(x,y,w,h)和getData(矩形)。 getData很酷,但我不想只需要光栅。我希望子图像作为BufferedImage对象,但我还需要它的数据数组的修改版本,但javadoc说 public BufferedImage getSubimage(int x,int y,int w,int h):返回由
下面的Docker图像有什么不同? null 哪个尺寸更小,可以在Spring Boot项目中使用?
我搜索过类似的问题,但没有找到解决方案。我有16位灰度图像,我正在尝试将它们放入keras ImageDataGenerator中。当使用诸如:flow_from_dataframe之类的函数时,它会生成所有具有相同像素值的图像(不正确)。 我尝试使用keras preprocess_输入,通过自定义预处理函数将其重新缩放到[0,1],再缩放到[-1,1],但这些都不起作用。我还在ImageDat