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"
This commit is contained in:
John Cupitt 2012-10-10 13:22:30 +01:00
parent 3e1b30dbf9
commit 2f65b07abb
5 changed files with 69 additions and 9 deletions

View File

@ -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)

View File

@ -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

View File

@ -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.

View File

@ -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;
/**

View File

@ -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}
};