def new_from_buffer(data, options, **kwargs): """Load a formatted image from memory. This behaves exactly as :meth:`new_from_file`, but the image is loaded from the memory object rather than from a file. The memory object can be anything that supports the Python buffer protocol. Args: data (array, bytearray, bytes, buffer): The memory object to load the image from. options (str): Load options as a string. Use ``""`` for no options. All loaders support at least the following options: Keyword args: access (Access): Hint the expected access pattern for the image. fail (bool): If set True, the loader will fail with an error on the first serious error in the image. By default, libvips will attempt to read everything it can from a damaged image. Returns: A new :class:`Image`. Raises: :class:`.Error` """ pointer = vips_lib.vips_foreign_find_load_buffer(data, len(data)) if pointer == ffi.NULL: raise Error('unable to load from buffer') name = _to_string(pointer) return pyvips.Operation.call(name, data, string_options=options, **kwargs)
def new_to_descriptor(descriptor): """Make a new target to write to a file descriptor (a small integer). Make a new target that is attached to the descriptor. For example:: target = pyvips.Target.new_to_descriptor(1) Makes a descriptor attached to stdout. You can pass this target to (for example) :meth:`write_to_target`. """ # logger.debug('VipsTarget.new_to_descriptor: descriptor = %d', # descriptor) # targets are mutable, so we can't use the cache pointer = vips_lib.vips_target_new_to_descriptor(descriptor) if pointer == ffi.NULL: raise Error( "can't create output target from descriptor {0}".format( descriptor)) return Target(pointer)
def signal_connect(self, name, callback): """Connect to a signal on this object. The callback will be triggered every time this signal is issued on this instance. It will be passed the image ('self' here), and a single `void *` pointer from libvips. The value of the pointer, if any, depends on the signal -- for example, ::eval passes a pointer to a `VipsProgress` struct. """ if name not in _marshalers: raise Error('unsupported signal "{0}"'.format(name)) go = ffi.cast('GObject *', self.pointer) handle = ffi.new_handle(callback) # we need to keep refs to the ffi handle and the callback to prevent # them being GCed # the callback might be a bound method (a closure) rather than a simple # function, so it can vanish self._handles.append(handle) self._handles.append(callback) gobject_lib.g_signal_connect_data(go, _to_bytes(name), _marshalers[name], handle, ffi.NULL, 0)
def new_from_memory(data): """Make a new source from a memory object. Make a new source that is attached to the memory object. For example:: source = pyvips.Source.new_from_memory("myfile.jpg") You can pass this source to (for example) :meth:`new_from_source`. The memory object can be anything that supports the Python buffer or memoryview protocol. """ # logger.debug('VipsSource.new_from_memory:') # py3: # - memoryview has .nbytes for number of bytes in object # - len() returns number of elements in top array # py2: # - buffer has no nbytes member # - but len() gives number of bytes in object start = ffi.from_buffer(data) nbytes = data.nbytes if hasattr(data, 'nbytes') else len(data) pointer = vips_lib.vips_source_new_from_memory(start, nbytes) if pointer == ffi.NULL: raise Error("can't create input source from memory") source = Source(pointer) # keep a secret reference to the input data to make sure it's not GCed source._references = [data] return source
def new_from_file(vips_filename, **kwargs): """Load an image from a file. This method can load images in any format supported by vips. The filename can include load options, for example:: image = pyvips.Image.new_from_file('fred.jpg[shrink=2]') You can also supply options as keyword arguments, for example:: image = pyvips.Image.new_from_file('fred.jpg', shrink=2) The full set of options available depend upon the load operation that will be executed. Try something like:: $ vips jpegload at the command-line to see a summary of the available options for the JPEG loader. Loading is fast: only enough of the image is loaded to be able to fill out the header. Pixels will only be decompressed when they are needed. Args: vips_filename (str): The disc file to load the image from, with optional appended arguments. All loaders support at least the following options: Keyword args: memory (bool): If set True, load the image via memory rather than via a temporary disc file. See :meth:`.new_temp_file` for notes on where temporary files are created. Small images are loaded via memory by default, use ``VIPS_DISC_THRESHOLD`` to set the definition of small. access (Access): Hint the expected access pattern for the image. fail (bool): If set True, the loader will fail with an error on the first serious error in the file. By default, libvips will attempt to read everything it can from a damanged image. Returns: A new :class:`.Image`. Raises: :class:`.Error` """ vips_filename = _to_bytes(vips_filename) filename = vips_lib.vips_filename_get_filename(vips_filename) options = vips_lib.vips_filename_get_options(vips_filename) name = vips_lib.vips_foreign_find_load(filename) if name == ffi.NULL: raise Error('unable to load from file {0}'.format(vips_filename)) return pyvips.Operation.call(_to_string(ffi.string(name)), _to_string(ffi.string(filename)), string_options=_to_string( ffi.string(options) ), **kwargs)
def new_from_memory(data, width, height, bands, format): """Wrap an image around a memory array. Wraps an Image around an area of memory containing a C-style array. For example, if the ``data`` memory array contains four bytes with the values 1, 2, 3, 4, you can make a one-band, 2x2 uchar image from it like this:: image = Image.new_from_memory(data, 2, 2, 1, 'uchar') A reference is kept to the data object, so it will not be garbage-collected until the returned image is garbage-collected. This method is useful for efficiently transferring images from PIL or NumPy into libvips. See :meth:`.write_to_memory` for the opposite operation. Use :meth:`.copy` to set other image attributes. Args: data (bytes): A memoryview or buffer object. width (int): Image width in pixels. height (int): Image height in pixels. bands (int): Number of bands. format (BandFormat): Band format. Returns: A new :class:`Image`. Raises: :class:`.Error` """ format_value = GValue.to_enum(GValue.format_type, format) pointer = ffi.from_buffer(data) # py3: # - memoryview has .nbytes for number of bytes in object # - len() returns number of elements in top array # py2: # - buffer has no nbytes member # - but len() gives number of bytes in object nbytes = data.nbytes if hasattr(data, 'nbytes') else len(data) vi = vips_lib.vips_image_new_from_memory(pointer, nbytes, width, height, bands, format_value) if vi == ffi.NULL: raise Error('unable to make image from memory') image = pyvips.Image(vi) # keep a secret ref to the underlying object .. this reference will be # inherited by things that in turn depend on us, so the memory we are # using will not be freed image._references.append(data) return image
def from_enum(gtype, enum_value): """Turn an int back into an enum string. """ pointer = vips_lib.vips_enum_nick(gtype, enum_value) if pointer == ffi.NULL: raise Error('value not in enum') return _to_string(pointer)
def from_enum(gtype, enum_value): """Turn an int back into an enum string. """ cstr = vips_lib.vips_enum_nick(gtype, enum_value) if cstr == 0: raise Error('value not in enum') return _to_string(ffi.string(cstr))
def fetch(self, x, y, w, h): """Fill a region with pixel data. Pixels are filled with data! Returns: Pixel data. Raises: :class:`.Error` """ if not at_least_libvips(8, 8): raise Error('libvips too old') psize = ffi.new('size_t *') pointer = vips_lib.vips_region_fetch(self.pointer, x, y, w, h, psize) if pointer == ffi.NULL: raise Error('unable to fetch from region') pointer = ffi.gc(pointer, glib_lib.g_free) return ffi.buffer(pointer, psize[0])
def to_enum(gtype, value): """Turn a string into an enum value ready to be passed into libvips. """ if isinstance(value, basestring if _is_PY2 else str): enum_value = vips_lib.vips_enum_from_nick(b'pyvips', gtype, _to_bytes(value)) if enum_value < 0: raise Error('no value {0} in gtype {1} ({2})'.format( value, type_name(gtype), gtype)) else: enum_value = value return enum_value
def get_args(self): args = [] if at_least_libvips(8, 7): p_names = ffi.new('char**[1]') p_flags = ffi.new('int*[1]') p_n_args = ffi.new('int[1]') result = vips_lib.vips_object_get_args(self.object, p_names, p_flags, p_n_args) if result != 0: raise Error('unable to get arguments from operation') p_names = p_names[0] p_flags = p_flags[0] n_args = p_n_args[0] for i in range(0, n_args): flags = p_flags[i] if (flags & _CONSTRUCT) != 0: name = _to_string(p_names[i]) # libvips uses '-' to separate parts of arg names, but we # need '_' for Python name = name.replace('-', '_') args.append([name, flags]) else: def add_construct(self, pspec, argument_class, argument_instance, a, b): flags = argument_class.flags if (flags & _CONSTRUCT) != 0: name = _to_string(pspec.name) # libvips uses '-' to separate parts of arg names, but we # need '_' for Python name = name.replace('-', '_') args.append([name, flags]) return ffi.NULL cb = ffi.callback('VipsArgumentMapFn', add_construct) vips_lib.vips_argument_map(self.object, cb, ffi.NULL, ffi.NULL) return args
def new_from_memory(data, width, height, bands, format): """Wrap an image around a memory array. Wraps an Image around an area of memory containing a C-style array. For example, if the ``data`` memory array contains four bytes with the values 1, 2, 3, 4, you can make a one-band, 2x2 uchar image from it like this:: image = Image.new_from_memory(data, 2, 2, 1, 'uchar') A reference is kept to the data object, so it will not be garbage-collected until the returned image is garbage-collected. This method is useful for efficiently transferring images from PIL or NumPy into libvips. See :meth:`.write_to_memory` for the opposite operation. Use :meth:`.copy` to set other image attributes. Args: data (bytes): A memoryview or buffer object. width (int): Image width in pixels. height (int): Image height in pixels. format (BandFormat): Band format. Returns: A new :class:`Image`. Raises: :class:`.Error` """ format_value = GValue.to_enum(GValue.format_type, format) vi = vips_lib.vips_image_new_from_memory(ffi.from_buffer(data), len(data), width, height, bands, format_value) if vi == ffi.NULL: raise Error('unable to make image from memory') image = pyvips.Image(vi) # keep a secret ref to the underlying object image._data = data return image
def new(image): """Make a region on an image. Returns: A new :class:`.Region`. Raises: :class:`.Error` """ pointer = vips_lib.vips_region_new(image.pointer) if pointer == ffi.NULL: raise Error('unable to make region') return pyvips.Region(pointer)
def get_typeof(self, name): """Get the GType of a GObject property. This function returns 0 if the property does not exist. """ # logger.debug('VipsObject.get_typeof: self = %s, name = %s', # str(self), name) pspec = self._get_pspec(name) if pspec is None: # need to clear any error, this is horrible Error('') return 0 return pspec.value_type
def new_to_file(filename): """Make a new target to write to a file. Make a new target that will write to the named file. For example:: target = pyvips.Target.new_to_file("myfile.jpg") You can pass this target to (for example) :meth:`write_to_target`. """ # logger.debug('VipsTarget.new_to_file: filename = %s', filename) pointer = vips_lib.vips_target_new_to_file(_to_bytes(filename)) if pointer == ffi.NULL: raise Error("can't create output target from filename {0}".format( filename)) return Target(pointer)
def version(flag): """Get the major, minor or micro version number of the libvips library. Args: flag (int): Pass flag 0 to get the major version number, flag 1 to get minor, flag 2 to get micro. Returns: The version number, Raises: :class:`.Error` """ value = vips_lib.vips_version(flag) if value < 0: raise Error('unable to get library version') return value
def get(self, name): """Get a GObject property. The value of the property is converted to a Python value. """ logger.debug('VipsObject.get: name = %s', name) pspec = self._get_pspec(name) if pspec is None: raise Error('Property not found.') gtype = pspec.value_type gv = pyvips.GValue() gv.set_type(gtype) go = ffi.cast('GObject *', self.pointer) gobject_lib.g_object_get_property(go, _to_bytes(name), gv.pointer) return gv.get()
def new_from_file(filename): """Make a new source from a filename. Make a new source that is attached to the named file. For example:: source = pyvips.Source.new_from_file("myfile.jpg") You can pass this source to (for example) :meth:`new_from_source`. """ # logger.debug('VipsSource.new_from_file: filename = %s', # filename) pointer = vips_lib.vips_source_new_from_file(_to_bytes(filename)) if pointer == ffi.NULL: raise Error("can't create source from filename {0}" .format(filename)) return Source(pointer)
def new_to_memory(): """Make a new target to write to an area of memory. Make a new target that will write to memory. For example:: target = pyvips.Target.new_to_memory() You can pass this target to (for example) :meth:`write_to_target`. After writing to the target, fetch the bytes from the target object with `target.get("blob")`. """ # logger.debug('VipsTarget.new_to_memory:') pointer = vips_lib.vips_target_new_to_memory() if pointer == ffi.NULL: raise Error("can't create output target from memory") return Target(pointer)