From 751982d9f04d2508c9176cbfb2f006b2a80b6d32 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 5 Sep 2014 14:53:05 +0100 Subject: [PATCH] add make vips matrix from python array --- TODO | 6 ++---- libvips/include/vips/image.h | 2 ++ libvips/iofuncs/header.c | 4 ++-- libvips/iofuncs/image.c | 38 ++++++++++++++++++++++++++++++++++++ python/try8.py | 16 +++++++++++++++ python/vips8/vips.py | 27 +++++++++++++++++++++++++ 6 files changed, 87 insertions(+), 6 deletions(-) create mode 100755 python/try8.py diff --git a/TODO b/TODO index 5606cc60..09d14f17 100644 --- a/TODO +++ b/TODO @@ -1,12 +1,10 @@ - python: - - something to make a mask from a list of lists - - - set scale and offset on mask - - how about the in-place things? draw a circle? + - try vips benchmark in vips8 python, how much slower? + - could import like this: from gi.repository import Vips diff --git a/libvips/include/vips/image.h b/libvips/include/vips/image.h index 9cb20e75..98622c76 100644 --- a/libvips/include/vips/image.h +++ b/libvips/include/vips/image.h @@ -423,6 +423,8 @@ VipsImage *vips_image_new_from_buffer( void *buf, size_t len, __attribute__((sentinel)); VipsImage *vips_image_new_matrix( int width, int height ); VipsImage *vips_image_new_matrixv( int width, int height, ... ); +VipsImage *vips_image_new_matrix_from_array( int width, int height, + double *array, int size ); void vips_image_set_delete_on_close( VipsImage *image, gboolean delete_on_close ); VipsImage *vips_image_new_temp_file( const char *format ); diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index 8707ace5..3ed2ae6c 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -837,7 +837,7 @@ vips_image_set( VipsImage *image, const char *field, GValue *value ) * vips_image_get: * @image: image to get the field from from * @field: the name to give the metadata - * @value_copy: the %GValue is copied into this + * @value_copy: (transfer full) (out caller-allocates): the %GValue is copied into this * * Fill @value_copy with a copy of the header field. @value_copy must be zeroed * but uninitialised. @@ -871,7 +871,7 @@ vips_image_set( VipsImage *image, const char *field, GValue *value ) * * See also: vips_image_get_typeof(), vips_image_get_double(). * - * Returns: 0 on success, -1 otherwise. + * Returns: (skip): 0 on success, -1 otherwise. */ int vips_image_get( const VipsImage *image, const char *field, GValue *value_copy ) diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 971098cd..bf56c7b7 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -2141,6 +2141,44 @@ vips_image_new_matrixv( int width, int height, ... ) return( matrix ); } +/** + * vips_image_new_matrix_from_array: + * @width: image width + * @height: image height + * @array: (array length=size) (transfer none): array of elements + * @size: number of elements + * + * A binding-friendly version of vips_image_new_matrixv(). + * + * Returns: the new #VipsImage, or %NULL on error. + */ +VipsImage * +vips_image_new_matrix_from_array( int width, int height, + double *array, int size ) +{ + VipsImage *matrix; + int x, y; + int i; + + if( size != width * height ) { + vips_error( "VipsImage", + _( "bad array length --- should be %d, you passed %d" ), + width * height, size ); + return( NULL ); + } + + vips_check_init(); + + matrix = vips_image_new_matrix( width, height ); + + i = 0; + for( y = 0; y < height; y++ ) + for( x = 0; x < width; x++ ) + *VIPS_MATRIX( matrix, x, y ) = array[i++]; + + return( matrix ); +} + /** * vips_image_set_delete_on_close: * @image: image to set diff --git a/python/try8.py b/python/try8.py new file mode 100755 index 00000000..42ff7309 --- /dev/null +++ b/python/try8.py @@ -0,0 +1,16 @@ +#!/usr/bin/python + +import sys + +#import logging +#logging.basicConfig(level = logging.DEBUG) + +from gi.repository import Vips +from vips8 import vips + +a = Vips.Image.new_from_array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], 8, 128) + +print 'scale =', a.get('scale') +print 'offset =', a.get('offset') + +a.write_to_file("x.v") diff --git a/python/vips8/vips.py b/python/vips8/vips.py index afb66c90..350ae994 100644 --- a/python/vips8/vips.py +++ b/python/vips8/vips.py @@ -218,6 +218,32 @@ def vips_image_new_from_buffer(cls, data, option_string, **kwargs): raise Error('No known loader for buffer.') logging.debug('Image.new_from_buffer: loader = %s' % loader) +# this is a class method +def vips_image_new_from_array(cls, array, scale = 1, offset = 0): + # we accept a 1D array and assume height == 1, or a 2D array and check all + # lines are the same length + if not isinstance(array, list): + raise TypeError('new_from_array() takes a list argument') + if not isinstance(array[0], list): + height = 1 + width = len(array) + else: + flat_array = array[0] + height = len(array) + width = len(array[0]) + for i in range(1, height): + if len(array[i]) != width: + raise TypeError('new_from_array() array not rectangular') + flat_array += array[i] + array = flat_array + + image = cls.new_matrix_from_array(width, height, array) + + image.set('scale', scale) + image.set('offset', offset) + + return image + def vips_image_getattr(self, name): logging.debug('Image.__getattr__ %s' % name) @@ -364,6 +390,7 @@ def vips_invert(self): # class methods setattr(Vips.Image, 'new_from_file', classmethod(vips_image_new_from_file)) setattr(Vips.Image, 'new_from_buffer', classmethod(vips_image_new_from_buffer)) +setattr(Vips.Image, 'new_from_array', classmethod(vips_image_new_from_array)) # instance methods Vips.Image.write_to_file = vips_image_write_to_file