def __init__(self, mode=None, size=None, color=None, source=None): """ ``mode`` must be one of the constants in the ``MODES`` set, ``size`` is a sequence of two integers (width and height of the new image); ``color`` is a sequence of integers, one for each component of the image, used to initialize all the pixels to the same value; ``source`` can be a sequence of integers of the appropriate size and format that is copied as-is in the buffer of the new image or an existing image; in Python 2.x ``source`` can also be an instance of ``str`` and is interpreted as a sequence of bytes. ``color`` and ``source`` are mutually exclusive and if they are both omitted the image is initialized to transparent black (all the bytes in the buffer have value 16 in the ``YV12`` mode, 255 in the ``CMYK*`` modes and 0 for everything else). If ``source`` is present and is an image, ``mode`` and/or ``size`` can be omitted; if they are specified and are different from the source mode and/or size, the source image is converted. """ self._mode = None self._size = None self._buffer = None self.info = {} if mode is not None: if mode not in MODES: raise ValueError("{} is not a valid mode.".format(mode)) self._mode = mode if size is not None: try: self._size = ImageSize(*size) except: raise ValueError("size must be an iterable returning 2 " "elements, not {}".format(size)) if source: # TODO: deal with source having a value if color: warnings.warn("color is disregarded when source is not None.") if isinstance(source, ImageMixin): if size: if size != source.size: # deal with resizing pass else: pass else: self._size = source.size if mode is None: self._mode = source.mode else: # deal with converting color pass else: # source had better be an iterable that we can stuff # into a buffer # python2 supports a byte string if util.py27 and isinstance(source, str): pass elif size and mode: assert self.size.width % self.mode.x_divisor == 0 assert self.size.height % self.mode.y_divisor == 0 if color and len(color) != self.components: raise ValueError( "color must be an iterable with {} values, " "one for each component in {}.".format(self.components, self.mode) ) # initialize buffer to the correct size and color _buffer = util.initialize_buffer(mode, size, color) # TODO: externalize this structure building stuff line_struct = type( "LineBuffer", (Line,), { "_fields_": [("pixels", mode.pixel_cls * self.size.width)], "image_cls": self.__class__, "mode": self.mode, }, ) image_struct = type("ImageBuffer", (_Image,), {"_fields_": [("lines", line_struct * self.size.height)]}) self._image_data = image_struct.from_buffer(_buffer) self._buffer = memoryview(_buffer) else: raise ValueError( "You must minimally specify a source from " "which to build the image or a mode and size " "with which to initialize the buffer." )
def setUpClass(cls): cls.pixels = {} for mode in MODES: buffer = util.initialize_buffer(mode, (1, 1)) cls.pixels[mode] = mode.pixel_cls.from_buffer(buffer)