【问题标题】:Convert CGImageRef to PIL将 CGImageRef 转换为 PIL
【发布时间】:2015-04-30 23:39:05
【问题描述】:

如何在不将图像保存到 osx 上的磁盘的情况下将 CGImageRef 转换为 PIL?

我想从 CGImageRef 获取原始像素数据并使用 Image.fromstring() 来制作 PIL 图像

import mss
import Quartz.CoreGraphics as CG
from PIL import Image

mss = mss.MSSMac()
for i, monitor in enumerate(mss.enum_display_monitors(0)):
    imageRef = mss.get_pixels(monitor)
    pixeldata = CG.CGDataProviderCopyData(CG.CGImageGetDataProvider(imageRef))
    img = Image.fromstring("RGB", (monitor[b'width'], monitor[b'height']), pixeldata)
    img.show()

但这并没有给我正确的图像。

这是我期望的图像:

这是我在 PIL 中得到的图像:

【问题讨论】:

  • 您能否添加一个最小但完整且可重现的场景供我们测试?如果你这样做,也许你会得到更好的答案。
  • 没有给出正确的图像是什么意思,它只是随机的垃圾还是看起来有点像你的图像?如果是后者,您至少可以提交预期的和实际的图像。
  • @Rachcha 我更新了正在使用的示例代码
  • @AnttiHaapala 它只是垃圾,与图像完全不同
  • 我添加了我期望得到的以及 PIL 图像是什么

标签: python macos python-imaging-library cgimage python-mss


【解决方案1】:

来自 CG 的屏幕截图不一定使用 RGB 颜色空间。它可能使用 RGBA 或其他东西。尝试改变:

img = Image.fromstring("RGB", (monitor[b'width'], monitor[b'height']), pixeldata)

img = Image.fromstring("RGBA", (monitor[b'width'], monitor[b'height']), pixeldata)

这是我检测实际捕获的色彩空间的方法:

bpp = CG.CGImageGetBitsPerPixel(imageRef)
info = CG.CGImageGetBitmapInfo(imageRef)
pixeldata = CG.CGDataProviderCopyData(CG.CGImageGetDataProvider(imageRef))

img = None
if bpp == 32:
    alphaInfo = info & CG.kCGBitmapAlphaInfoMask
    if alphaInfo == CG.kCGImageAlphaPremultipliedFirst or alphaInfo == CG.kCGImageAlphaFirst or alphaInfo == CG.kCGImageAlphaNoneSkipFirst:
        img = Image.fromstring("RGBA", (CG.CGImageGetWidth(imageRef), CG.CGImageGetHeight(imageRef)), pixeldata, "raw", "BGRA")
    else:
        img = Image.fromstring("RGBA", (CG.CGImageGetWidth(imageRef), CG.CGImageGetHeight(imageRef)), pixeldata)
elif bpp == 24:
    img = Image.fromstring("RGB", (CG.CGImageGetWidth(imageRef), CG.CGImageGetHeight(imageRef)), pixeldata)

【讨论】:

    【解决方案2】:

    这是我前段时间修复的一个错误。以下是如何使用最新的 mss 版本 (2.0.22) 实现您想要的:

    from mss.darwin import MSS
    from PIL import Image
    
    with MSS() as mss:
        for monitor in mss.enum_display_monitors(0):
            pixeldata = mss.get_pixels(monitor)
            img = Image.frombytes('RGB', (mss.width, mss.height), pixeldata)
            img.show()
    

    注意pixeldata只是对mss.image的引用,可以直接使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-03
      • 1970-01-01
      • 1970-01-01
      • 2017-01-24
      • 2011-06-01
      • 1970-01-01
      相关资源
      最近更新 更多