def new_temp_file(format): """Make a new temporary image. Returns an image backed by a temporary file. When written to with :func:`Image.write`, a temporary file will be created on disc in the specified format. When the image is closed, the file will be deleted automatically. The file is created in the temporary directory. This is set with the environment variable ``TMPDIR``. If this is not set, then on Unix systems, vips will default to ``/tmp``. On Windows, vips uses ``GetTempPath()`` to find the temporary directory. vips uses ``g_mkstemp()`` to make the temporary filename. They generally look something like ``"vips-12-EJKJFGH.v"``. Args: format (str): The format for the temp file, for example ``"%s.v"`` for a vips format file. The ``%s`` is substituted by the file path. Returns: A new :class:`Image`. Raises: :class:`.Error` """ vi = vips_lib.vips_image_new_temp_file(_to_bytes(format)) if vi == ffi.NULL: raise Error('unable to make temp file') return pyvips.Image(vi)
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 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 copy_memory(self): """Copy an image to memory. A large area of memory is allocated, the image is rendered to that memory area, and a new image is returned which wraps that large memory area. Returns: A new :class:`Image`. Raises: :class:`.Error` """ vi = vips_lib.vips_image_copy_memory(self.pointer) if vi == ffi.NULL: raise Error('unable to copy to memory') return pyvips.Image(vi)
def new_from_array(array, scale=1.0, offset=0.0): """Create an image from a 1D or 2D array. A new one-band image with :class:`BandFormat` ``'double'`` pixels is created from the array. These image are useful with the libvips convolution operator :meth:`Image.conv`. Args: array (list[list[float]]): Create the image from these values. 1D arrays become a single row of pixels. scale (float): Default to 1.0. What to divide each pixel by after convolution. Useful for integer convolution masks. offset (float): Default to 0.0. What to subtract from each pixel after convolution. Useful for integer convolution masks. Returns: A new :class:`Image`. Raises: :class:`.Error` """ if not _is_2D(array): array = [array] height = len(array) width = len(array[0]) n = width * height a = ffi.new('double[]', n) for y in range(0, height): for x in range(0, width): a[x + y * width] = array[y][x] vi = vips_lib.vips_image_new_matrix_from_array(width, height, a, n) if vi == ffi.NULL: raise Error('unable to make image from matrix') image = pyvips.Image(vi) image.set_type(GValue.gdouble_type, 'scale', scale) image.set_type(GValue.gdouble_type, 'offset', offset) return image
def get(self): """Get the contents of a GValue. The contents of the GValue are read out as a Python type. """ # logger.debug('GValue.get: self = %s', self) gtype = self.gvalue.g_type fundamental = gobject_lib.g_type_fundamental(gtype) result = None if gtype == GValue.gbool_type: result = bool(gobject_lib.g_value_get_boolean(self.gvalue)) elif gtype == GValue.gint_type: result = gobject_lib.g_value_get_int(self.gvalue) elif gtype == GValue.gdouble_type: result = gobject_lib.g_value_get_double(self.gvalue) elif fundamental == GValue.genum_type: return GValue.from_enum(gtype, gobject_lib.g_value_get_enum(self.gvalue)) elif fundamental == GValue.gflags_type: result = gobject_lib.g_value_get_flags(self.gvalue) elif gtype == GValue.gstr_type: pointer = gobject_lib.g_value_get_string(self.gvalue) if pointer != ffi.NULL: result = _to_string(pointer) elif gtype == GValue.refstr_type: psize = ffi.new('size_t *') pointer = vips_lib.vips_value_get_ref_string(self.gvalue, psize) # psize[0] will be number of bytes in string, but just assume it's # NULL-terminated result = _to_string(pointer) elif gtype == GValue.image_type: # g_value_get_object() will not add a ref ... that is # held by the gvalue go = gobject_lib.g_value_get_object(self.gvalue) vi = ffi.cast('VipsImage *', go) # we want a ref that will last with the life of the vimage: # this ref is matched by the unref that's attached to finalize # by Image() gobject_lib.g_object_ref(go) result = pyvips.Image(vi) elif gtype == GValue.array_int_type: pint = ffi.new('int *') array = vips_lib.vips_value_get_array_int(self.gvalue, pint) result = [] for i in range(0, pint[0]): result.append(array[i]) elif gtype == GValue.array_double_type: pint = ffi.new('int *') array = vips_lib.vips_value_get_array_double(self.gvalue, pint) result = [] for i in range(0, pint[0]): result.append(array[i]) elif gtype == GValue.array_image_type: pint = ffi.new('int *') array = vips_lib.vips_value_get_array_image(self.gvalue, pint) result = [] for i in range(0, pint[0]): vi = array[i] gobject_lib.g_object_ref(vi) image = pyvips.Image(vi) result.append(image) elif gtype == GValue.blob_type: psize = ffi.new('size_t *') array = vips_lib.vips_value_get_blob(self.gvalue, psize) buf = ffi.cast('char*', array) result = ffi.unpack(buf, psize[0]) else: raise Error('unsupported gtype for get {0}'.format( type_name(gtype))) return result
def _marshal_image_progress(vi, pointer, handle): gobject_lib.g_object_ref(vi) image = pyvips.Image(vi) callback = ffi.from_handle(handle) progress = ffi.cast('VipsProgress*', pointer) callback(image, progress)