2016-05-08 21 views
0

ctypesモジュールのみを使用して画面をキャプチャしようとしています。残念ながら、CGDataProviderCopyDataから生のピクセルを取得できません。生データにアクセスする必要があります:OS Xとctypes:CGDataProviderCopyData()から生のピクセルを取得する方法?

#!/usr/bin/env python 
# coding: utf-8 

from sys import maxsize 
from ctypes import POINTER, Structure, c_double, byref, c_void_p, c_int32, c_uint32, c_float, cdll 
from ctypes.util import find_library 


CGFloat = c_double if maxsize > 2 ** 32 else c_float 


class CGPoint(Structure): 
    _fields_ = [('x', CGFloat), ('y', CGFloat)] 


class CGSize(Structure): 
    _fields_ = [('width', CGFloat), ('height', CGFloat)] 


class CGRect(Structure): 
    _fields_ = [('origin', CGPoint), ('size', CGSize)] 


# Library 
cgs = cdll.LoadLibrary(find_library('CoreGraphics')) 

# Argtypes 
cgs.CGGetActiveDisplayList.argtypes = [c_uint32, POINTER(c_uint32), POINTER(c_uint32)] 
cgs.CGDisplayBounds.argtypes = [c_uint32] 
cgs.CGRectStandardize.argtypes = [CGRect] 
cgs.CGDisplayRotation.argtypes = [c_uint32] 
cgs.CGWindowListCreateImage.argtypes = [CGRect, c_uint32, c_uint32, c_uint32] 
cgs.CGImageGetWidth.argtypes = [c_void_p] 
cgs.CGImageGetHeight.argtypes = [c_void_p] 
cgs.CGImageGetDataProvider.argtypes = [c_void_p] 
cgs.CGDataProviderCopyData.argtypes = [c_void_p] 
cgs.CGDataProviderRelease.argtypes = [c_void_p] 

# Restypes 
cgs.CGGetActiveDisplayList.restype = c_int32 
cgs.CGDisplayBounds.restype = CGRect 
cgs.CGRectStandardize.restype = CGRect 
cgs.CGDisplayRotation.restype = c_float 
cgs.CGWindowListCreateImage.restype = c_void_p 
cgs.CGImageGetWidth.restype = c_uint32 
cgs.CGImageGetHeight.restype = c_uint32 
cgs.CGImageGetDataProvider.restype = c_void_p 
cgs.CGDataProviderCopyData.restype = c_void_p 
cgs.CGDataProviderRelease.restype = c_void_p 

# Monitors 
max_displays = 32 
display_count = c_uint32(0) 
active_displays = (c_uint32 * max_displays)() 
cgs.CGGetActiveDisplayList(max_displays, active_displays, byref(display_count)) 
for idx in range(display_count.value): 
    display = active_displays[idx] 
    rect = cgs.CGDisplayBounds(display) 
    rect = cgs.CGRectStandardize(rect) 

    image_ref = cgs.CGWindowListCreateImage(rect, 1, 0, 0) 
    width = int(cgs.CGImageGetWidth(image_ref)) 
    height = int(cgs.CGImageGetHeight(image_ref)) 
    prov = cgs.CGImageGetDataProvider(image_ref) 
    data = cgs.CGDataProviderCopyData(prov) 

    # How to get raw pixels from data`? 

MacOS Xバージョン10.11.3。

Pythonバージョン2.7.10および2.6.9。

答えて

1

おかげで、私は最終的に成功する:

#... 
data = cgs.CGDataProviderCopyData(prov) 
data_ref = cgs.CFDataGetBytePtr(data) 
buf_len = cgs.CFDataGetLength() 
image_data = cast(data_ref, POINTER(c_ubyte * buf_len)) 
cgs.CGDataProviderRelease(prov) 

# Raw pixels are in image_data.contents 
1

私はCoreGraphics APIに関する経験はありませんが、CGDataProviderCopyDataのようなドキュメントを見るとCFDataRefオブジェクトを返します。 CFDataRefのドキュメンテーションには、CFDataGetLength関数と、データの長さを返すCFDataGetBytePtr関数と、UInt8*を記述する「CFDataオブジェクトの調査」に関するセクションがあります。 Snorfalorpagusへ

https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGDataProvider/#//apple_ref/c/func/CGDataProviderCopyData

https://developer.apple.com/library/ios/documentation/CoreFoundation/Reference/CFDataRef/index.html

関連する問題