Beispiel #1
0
    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)
Beispiel #2
0
    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)
Beispiel #3
0
    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)
Beispiel #4
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
Beispiel #5
0
    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)
Beispiel #6
0
    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
Beispiel #7
0
    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)
Beispiel #8
0
    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))
Beispiel #9
0
    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])
Beispiel #10
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
Beispiel #11
0
    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
Beispiel #12
0
    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
Beispiel #13
0
    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)
Beispiel #14
0
    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
Beispiel #15
0
    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)
Beispiel #16
0
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
Beispiel #17
0
    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()
Beispiel #18
0
    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)
Beispiel #19
0
    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)