2015-02-28 1 views
0

Comment convertir un CGImageRef en PIL sans enregistrer l'image sur le disque sous osx?Conversion de CGImageRef en PIL

Je pensais à obtenir les données brutes des pixels du CGImageRef et en utilisant Image.fromstring() pour rendre l'image PIL en faisant

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() 

mais cela ne me donne pas l'image correcte.

C'est l'image que je pense:

enter image description here

et c'est l'image que je reçois dans PIL:

enter image description here

+2

Pourriez-vous s'il vous plaît ajouter un scénario minimal mais complet et reproductible pour nous de tester? Peut-être que vous obtiendrez de meilleures réponses si vous le faites. – Rachcha

+0

Qu'est-ce que * ne donne pas une image correcte * signifie, est-ce juste de la camelote ou ressemble-t-il un peu à votre image? Si ce dernier vous pouvez au moins soumettre l'image attendue et réelle. –

+0

@Rachcha J'ai mis à jour l'exemple de code qui est utilisé – nom3kop

Répondre

0

Le screencapture de CG n'utilise pas nécessairement le RGB espace de couleurs. Il peut utiliser RGBA ou autre chose. Essayez de changer:

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

à

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

Voici comment je perçois qui colorspace est effectivement capturé:

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

Il était un bug je fixe il y a quelque temps . Voici comment obtenir ce que vous voulez utiliser la dernière version 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() 

Notez que pixeldata est juste une référence à mss.image, vous pouvez l'utiliser directement.