_re_buffer_address = re.compile('<read-write buffer ptr 0x([0-9a-f]*),') global _re_buffer_address_match _re_buffer_address_match = _re_buffer_address.match return _re_buffer_address_match(buf_repr) def PySide_data(image): # PySide's QImage.bits() returns a buffer object like this: # <read-write buffer ptr 0x7fc3f4821600, size 76800 at 0x111269570> ma = _re_buffer_address_match(repr(image.bits())) assert ma, 'could not parse address from %r' % (image.bits(), ) return (int(ma.group(1), 16), False) getdata = dict( PyQt4 = PyQt4_data, PySide = PySide_data, )[qt.name()] def qimageview(image): if not isinstance(image, QtGui.QImage): raise TypeError("image argument must be a QImage instance") shape = image.height(), image.width() strides0 = image.bytesPerLine() format = image.format() if format == QtGui.QImage.Format_Indexed8: dtype = "|u1" strides1 = 1 elif format in (QtGui.QImage.Format_RGB32, QtGui.QImage.Format_ARGB32, QtGui.QImage.Format_ARGB32_Premultiplied): dtype = "|u4"
return image.bits() # I would have preferred a more pythonic (duck-typing-like) approach # based on introspection, but finding out which one of the above functions # works at runtime is quite hard getdata = { ('PyQt4', 2) : PyQt_data, ('PyQt5', 2) : PyQt_data, ('PySide', 2) : PySide_data, ('PySide2', 2) : PySide_data, ('PyQt4', 3) : PyQt_data, ('PyQt5', 3) : PyQt_data, ('PySide', 3) : direct_buffer_data, ('PySide2', 3) : direct_buffer_data, ('PythonQt', 3) : direct_buffer_data, }[qt.name(), sys.version_info.major] VALIDFORMATS_8BIT = tuple( getattr(QtGui.QImage, name) for name in ('Format_Indexed8', 'Format_Grayscale8') if name in dir(QtGui.QImage)) VALIDFORMATS_32BIT = ( QtGui.QImage.Format_RGB32, QtGui.QImage.Format_ARGB32, QtGui.QImage.Format_ARGB32_Premultiplied) class ArrayInterfaceAroundQImage(object): __slots__ = ('__qimage', '__array_interface__') def __init__(self, image, bytes_per_pixel): self.__qimage = image
# I would have preferred a more pythonic (duck-typing-like) approach # based on introspection, but finding out which one of the above functions # works at runtime is quite hard getdata = { ('PyQt4', 2): PyQt_data, ('PyQt5', 2): PyQt_data, ('PySide', 2): PySide_data, ('PySide2', 2): PySide_data, ('PyQt4', 3): PyQt_data, ('PyQt5', 3): PyQt_data, ('PySide', 3): direct_buffer_data, ('PySide2', 3): direct_buffer_data, ('PythonQt', 3): direct_buffer_data, }[qt.name(), sys.version_info.major] # what properties (e.g., how many bits) do the different formats have? class QImageFormat(object): def __init__(self, bits, rgb_layout=None): self.code = None self.bits = bits self.rgb_layout = rgb_layout @staticmethod def from_code(code): for name, qimage_format in FORMATS.items(): if qimage_format.code == code: return qimage_format
return _re_buffer_address_match(buf_repr) def PySide_data(image): # PySide's QImage.bits() returns a buffer object like this: # <read-write buffer ptr 0x7fc3f4821600, size 76800 at 0x111269570> ma = _re_buffer_address_match(repr(image.bits())) assert ma, 'could not parse address from %r' % (image.bits(), ) return (int(ma.group(1), 16), False) getdata = dict( PyQt4=PyQt_data, PyQt5=PyQt_data, PySide=PySide_data, )[qt.name()] def qimageview(image): if not isinstance(image, QtGui.QImage): raise TypeError("image argument must be a QImage instance") shape = image.height(), image.width() strides0 = image.bytesPerLine() format = image.format() if format == QtGui.QImage.Format_Indexed8: dtype = "|u1" strides1 = 1 elif format in (QtGui.QImage.Format_RGB32, QtGui.QImage.Format_ARGB32, QtGui.QImage.Format_ARGB32_Premultiplied):