2015-02-28 5 views
0

Как я могу преобразовать CGImageRef в PIL, не сохраняя изображение на диск в 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() 

, но это не дает мне правильное изображение.

Это изображение, которое я ожидал:

enter image description here

и это изображение я получаю в PIL:

enter image description here

+2

Не могли бы вы добавить минимальный, но полный и воспроизводимый сценарий для нас? Возможно, вы получите лучшие ответы, если вы это сделаете. – Rachcha

+0

Что означает * не дает правильного изображения * означает, что это просто случайный мусор или он немного похож на ваш образ? Если последнее вы могли бы представить как ожидаемое, так и фактическое изображение. –

+0

@ Rachcha Я обновил код примера, который используется – nom3kop

ответ

0

ScreenCapture из 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) 
0

Это была ошибка я исправил некоторое время назад , Вот как добиться того, что вы хотите использовать последнюю версию 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, вы можете использовать его непосредственно.