From 2f65b07abb6a4701133a8420e7c4ce20b62b312f Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 10 Oct 2012 13:22:30 +0100 Subject: [PATCH] add a @background option to embed and dzsave you can now set the background colour for edge tiles in dzsave and embed, eg.: vips dzsave k2.jpg x --background "1 2 3" --- ChangeLog | 2 ++ libvips/conversion/embed.c | 39 +++++++++++++++++++++++++++++-- libvips/foreign/dzsave.c | 20 +++++++++++++++- libvips/include/vips/conversion.h | 16 ++++++++----- libvips/iofuncs/enumtypes.c | 1 + 5 files changed, 69 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1f301da9..1fe064b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 3/10/12 started 7.31.0 - dzsave can write zoomify and google maps layout as well +- embed has 'background' option +- dzsave --layout google has a @background option 2/10/12 started 7.30.4 - remove options from format string in .dzi (thanks Martin) diff --git a/libvips/conversion/embed.c b/libvips/conversion/embed.c index 81641b2e..1cc7894b 100644 --- a/libvips/conversion/embed.c +++ b/libvips/conversion/embed.c @@ -23,6 +23,8 @@ * - cleanups * 15/10/11 * - rewrite as a class + * 10/10/12 + * - add @background */ /* @@ -79,11 +81,16 @@ typedef struct _VipsEmbed { VipsImage *in; VipsExtend extend; + VipsArea *background; int x; int y; int width; int height; + /* Pixel we paint calculated from background. + */ + VipsPel *ink; + /* Geometry calculations. */ VipsRect rout; /* Whole output area */ @@ -257,6 +264,14 @@ vips_embed_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop ) embed->extend == 0 ? 0 : 255 ); break; + case VIPS_EXTEND_BACKGROUND: + /* Paint the borders a solid value. + */ + for( i = 0; i < 8; i++ ) + vips_region_paint_pel( or, &embed->border[i], + embed->ink ); + break; + case VIPS_EXTEND_COPY: /* Extend the borders. */ @@ -327,6 +342,15 @@ vips_embed_build( VipsObject *object ) if( vips_image_pio_input( embed->in ) ) return( -1 ); + if( !(embed->ink = vips__vector_to_ink( + "VipsEmbed", embed->in, + embed->background->data, embed->background->n )) ) + return( -1 ); + + if( !vips_object_get_argument_assigned( object, "extend" ) && + vips_object_get_argument_assigned( object, "background" ) ) + embed->extend = VIPS_EXTEND_BACKGROUND; + switch( embed->extend ) { case VIPS_EXTEND_REPEAT: { @@ -398,6 +422,7 @@ vips_embed_build( VipsObject *object ) case VIPS_EXTEND_BLACK: case VIPS_EXTEND_WHITE: + case VIPS_EXTEND_BACKGROUND: case VIPS_EXTEND_COPY: if( vips_image_copy_fields( conversion->out, embed->in ) ) return( -1 ); @@ -559,13 +584,22 @@ vips_embed_class_init( VipsEmbedClass *class ) VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET( VipsEmbed, extend ), VIPS_TYPE_EXTEND, VIPS_EXTEND_BLACK ); + + VIPS_ARG_BOXED( class, "background", 12, + _( "Background" ), + _( "Colour for background pixels" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsEmbed, background ), + VIPS_TYPE_ARRAY_DOUBLE ); } static void vips_embed_init( VipsEmbed *embed ) { - /* Init our instance fields. - */ + embed->extend = VIPS_EXTEND_BLACK; + embed->background = + vips_area_new_array( G_TYPE_DOUBLE, sizeof( double ), 1 ); + ((double *) (embed->background->data))[0] = 0; } /** @@ -581,6 +615,7 @@ vips_embed_init( VipsEmbed *embed ) * Optional arguments: * * @extend: how to generate the edge pixels + * @background: colour for edge pixels * * The opposite of vips_extract_area(): embed @in within an image of size * @width by @height at position @x, @y. @extend diff --git a/libvips/foreign/dzsave.c b/libvips/foreign/dzsave.c index 0b3a200a..5f40f75e 100644 --- a/libvips/foreign/dzsave.c +++ b/libvips/foreign/dzsave.c @@ -24,6 +24,8 @@ * - remove filename options from format string in .dzi (thanks Martin) * 3/10/12 * - add zoomify and google maps output + * 10/10/12 + * - add @background option */ /* @@ -131,6 +133,7 @@ struct _VipsForeignSaveDz { int overlap; int tile_size; VipsForeignDzLayout layout; + VipsArea *background; Layer *layer; /* x2 shrink pyr layer */ @@ -703,7 +706,7 @@ strip_work( VipsThreadState *state, void *a ) VipsImage *z; if( vips_embed( x, &z, 0, 0, dz->tile_size, dz->tile_size, - "extend", VIPS_EXTEND_WHITE, + "background", dz->background, NULL ) ) { g_object_unref( x ); return( -1 ); @@ -1133,6 +1136,13 @@ vips_foreign_save_dz_class_init( VipsForeignSaveDzClass *class ) G_STRUCT_OFFSET( VipsForeignSaveDz, tile_size ), 1, 1024, 256 ); + VIPS_ARG_BOXED( class, "background", 12, + _( "Background" ), + _( "Colour for background pixels" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsForeignSaveDz, background ), + VIPS_TYPE_ARRAY_DOUBLE ); + /* How annoying. We stupidly had these in earlier versions. */ @@ -1167,6 +1177,9 @@ vips_foreign_save_dz_init( VipsForeignSaveDz *dz ) dz->overlap = 1; dz->tile_size = 256; dz->tile_count = 0; + dz->background = + vips_area_new_array( G_TYPE_DOUBLE, sizeof( double ), 1 ); + ((double *) (dz->background->data))[0] = 255; } /** @@ -1181,6 +1194,7 @@ vips_foreign_save_dz_init( VipsForeignSaveDz *dz ) * @suffix: suffix for tile tiles * @overlap; set tile overlap * @tile_size; set tile size + * @background: background colour * * Save an image as a set of tiles at various resolutions. By default dzsave * uses DeepZoom layout -- use @layout to pick other conventions. @@ -1194,6 +1208,10 @@ vips_foreign_save_dz_init( VipsForeignSaveDz *dz ) * * You can set @suffix to something like ".jpg[Q=85]" to set the tile write * options. + * + * In Google layout mode, edge tiles are expanded to @tile_size by @tile_size + * pixels. Normally they are filled with white, but you can set another colour + * with @background. * * You can set the size and overlap of tiles with @tile_size and @overlap. * They default to the correct settings for the selected @layout. diff --git a/libvips/include/vips/conversion.h b/libvips/include/vips/conversion.h index 3467d200..3c63035c 100644 --- a/libvips/include/vips/conversion.h +++ b/libvips/include/vips/conversion.h @@ -44,6 +44,7 @@ extern "C" { * @VIPS_EXTEND_REPEAT: repeat the whole image * @VIPS_EXTEND_MIRROR: mirror the whole image * @VIPS_EXTEND_WHITE: extend with white (all bits set) pixels + * @VIPS_EXTEND_BACKGROUND: extend with colour from the @background property * * See vips_embed(), vips_conv(), vips_affine() and so on. * @@ -61,6 +62,8 @@ extern "C" { * edges * * #VIPS_EXTEND_WHITE --- new pixels are white, ie. all bits are set + + * #VIPS_EXTEND_BACKGROUND --- colour set from the @background property * * We have to specify the exact value of each enum member since we have to * keep these frozen for back compat with vips7. @@ -68,12 +71,13 @@ extern "C" { * See also: vips_embed(). */ typedef enum { - VIPS_EXTEND_BLACK = 0, - VIPS_EXTEND_COPY = 1, - VIPS_EXTEND_REPEAT = 2, - VIPS_EXTEND_MIRROR = 3, - VIPS_EXTEND_WHITE = 4, - VIPS_EXTEND_LAST = 5 + VIPS_EXTEND_BLACK, + VIPS_EXTEND_COPY, + VIPS_EXTEND_REPEAT, + VIPS_EXTEND_MIRROR, + VIPS_EXTEND_WHITE, + VIPS_EXTEND_BACKGROUND, + VIPS_EXTEND_LAST } VipsExtend; /** diff --git a/libvips/iofuncs/enumtypes.c b/libvips/iofuncs/enumtypes.c index ba7b357a..a7e44f1a 100644 --- a/libvips/iofuncs/enumtypes.c +++ b/libvips/iofuncs/enumtypes.c @@ -137,6 +137,7 @@ vips_extend_get_type( void ) {VIPS_EXTEND_REPEAT, "VIPS_EXTEND_REPEAT", "repeat"}, {VIPS_EXTEND_MIRROR, "VIPS_EXTEND_MIRROR", "mirror"}, {VIPS_EXTEND_WHITE, "VIPS_EXTEND_WHITE", "white"}, + {VIPS_EXTEND_BACKGROUND, "VIPS_EXTEND_BACKGROUND", "background"}, {VIPS_EXTEND_LAST, "VIPS_EXTEND_LAST", "last"}, {0, NULL, NULL} };