add --centre option to dzsave

with --centre turned on, in google maps mode dzsave will centre tiles
rather than placing them at the top-left

also, make sure blank.png is set to @background
This commit is contained in:
John Cupitt 2013-01-21 14:48:14 +00:00
parent b2cd5f631e
commit 9fb16c23fc
3 changed files with 150 additions and 49 deletions

View File

@ -35,6 +35,7 @@
- redone im_affine*() as a class - redone im_affine*() as a class
- added input space displacement to affine - added input space displacement to affine
- VipsArea is threadsafe - VipsArea is threadsafe
- dzsave has a --centre option
31/12/12 started 7.30.7 31/12/12 started 7.30.7
- better option parsing for "vips", thanks Haida - better option parsing for "vips", thanks Haida

View File

@ -28,6 +28,8 @@
* - add @background option * - add @background option
* 1/11/12 * 1/11/12
* - add @depth option * - add @depth option
* 21/1/13
* - add @centre option
*/ */
/* /*
@ -135,8 +137,9 @@ struct _VipsForeignSaveDz {
int overlap; int overlap;
int tile_size; int tile_size;
VipsForeignDzLayout layout; VipsForeignDzLayout layout;
VipsArea *background; VipsArrayDouble *background;
VipsForeignDzDepth depth; VipsForeignDzDepth depth;
gboolean centre;
Layer *layer; /* x2 shrink pyr layer */ Layer *layer; /* x2 shrink pyr layer */
@ -367,18 +370,39 @@ static int
write_blank( VipsForeignSaveDz *dz ) write_blank( VipsForeignSaveDz *dz )
{ {
char buf[PATH_MAX]; char buf[PATH_MAX];
VipsImage *black; VipsImage *x, *t;
int n;
VipsArea *ones;
double *d;
int i;
vips_snprintf( buf, PATH_MAX, "%s/blank.png", dz->basename ); vips_snprintf( buf, PATH_MAX, "%s/blank.png", dz->basename );
if( vips_black( &black, dz->tile_size, dz->tile_size, if( vips_black( &x, dz->tile_size, dz->tile_size, NULL ) )
"bands", 3,
NULL ) )
return( -1 ); return( -1 );
if( vips_image_write_to_file( black, buf ) ) {
g_object_unref( black ); vips_area_get_data( (VipsArea *) dz->background, NULL, &n, NULL, NULL );
ones = vips_area_new_array( G_TYPE_DOUBLE, sizeof( double ), n );
d = (double *) vips_area_get_data( ones, NULL, NULL, NULL, NULL );
for( i = 0; i < n; i++ )
d[i] = 1.0;
if( vips_linear( x, &t,
d,
(double *) vips_area_get_data( (VipsArea *) dz->background,
NULL, NULL, NULL, NULL ),
n, NULL ) ) {
vips_area_unref( ones );
g_object_unref( x );
return( -1 ); return( -1 );
} }
g_object_unref( black ); vips_area_unref( ones );
g_object_unref( x );
x = t;
if( vips_image_write_to_file( x, buf ) ) {
g_object_unref( x );
return( -1 );
}
g_object_unref( x );
return( 0 ); return( 0 );
} }
@ -708,8 +732,9 @@ strip_work( VipsThreadState *state, void *a )
Layer *layer = strip->layer; Layer *layer = strip->layer;
VipsForeignSaveDz *dz = layer->dz; VipsForeignSaveDz *dz = layer->dz;
VipsImage *x;
char buf[PATH_MAX]; char buf[PATH_MAX];
VipsImage *x;
VipsImage *t;
#ifdef DEBUG #ifdef DEBUG
printf( "strip_work\n" ); printf( "strip_work\n" );
@ -731,9 +756,7 @@ strip_work( VipsThreadState *state, void *a )
/* Google tiles need to be padded up to tilesize. /* Google tiles need to be padded up to tilesize.
*/ */
if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_GOOGLE ) { if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_GOOGLE ) {
VipsImage *z; if( vips_embed( x, &t, 0, 0, dz->tile_size, dz->tile_size,
if( vips_embed( x, &z, 0, 0, dz->tile_size, dz->tile_size,
"background", dz->background, "background", dz->background,
NULL ) ) { NULL ) ) {
g_object_unref( x ); g_object_unref( x );
@ -741,7 +764,35 @@ strip_work( VipsThreadState *state, void *a )
} }
g_object_unref( x ); g_object_unref( x );
x = z; x = t;
}
/* If we are centreing we may have a tile which is entirely blank.
* Skip the write in this case, the viewer will use blank.png instead.
*/
if( dz->centre ) {
double *d;
int n;
double m;
d = (double *) vips_area_get_data( (VipsArea *) dz->background,
NULL, &n, NULL, NULL );
if( vips_equal_const( x, &t, d, n, NULL ) ) {
g_object_unref( x );
return( -1 );
}
if( vips_min( t, &m, NULL ) ) {
g_object_unref( x );
g_object_unref( t );
return( -1 );
}
g_object_unref( t );
if( m == 255 ) {
g_object_unref( x );
return( 0 );
}
} }
#ifdef DEBUG #ifdef DEBUG
@ -1091,6 +1142,45 @@ vips_foreign_save_dz_build( VipsObject *object )
build( object ) ) build( object ) )
return( -1 ); return( -1 );
/* For centred images, imagine shrinking so that the image fits in a
* single tile, centering in that tile, then expanding back again.
*/
if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_GOOGLE &&
dz->centre ) {
VipsImage *z;
Layer *layer;
int n_layers;
int size;
if( !(layer = pyramid_build( dz,
NULL, save->ready->Xsize, save->ready->Ysize )) )
return( -1 );
n_layers = layer->n;
/* This would cause interesting problems.
*/
g_assert( n_layers < 30 );
layer_free( layer );
size = dz->tile_size * (1 << n_layers);
if( vips_embed( save->ready, &z,
(size - save->ready->Xsize) / 2,
(size - save->ready->Ysize) / 2,
size, size,
"background", dz->background,
NULL ) )
return( -1 );
VIPS_UNREF( save->ready );
save->ready = z;
#ifdef DEBUG
printf( "centre: centreing within a %d x %d image\n",
size, size );
#endif
}
/* Build the skeleton of the image pyramid. /* Build the skeleton of the image pyramid.
*/ */
if( !(dz->layer = pyramid_build( dz, if( !(dz->layer = pyramid_build( dz,
@ -1219,6 +1309,13 @@ vips_foreign_save_dz_class_init( VipsForeignSaveDzClass *class )
VIPS_TYPE_FOREIGN_DZ_DEPTH, VIPS_TYPE_FOREIGN_DZ_DEPTH,
VIPS_FOREIGN_DZ_DEPTH_1PIXEL ); VIPS_FOREIGN_DZ_DEPTH_1PIXEL );
VIPS_ARG_BOOL( class, "centre", 13,
_( "Center" ),
_( "Center image in tile" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsForeignSaveDz, centre ),
FALSE );
/* How annoying. We stupidly had these in earlier versions. /* How annoying. We stupidly had these in earlier versions.
*/ */
@ -1270,6 +1367,7 @@ vips_foreign_save_dz_init( VipsForeignSaveDz *dz )
* @tile_size; set tile size * @tile_size; set tile size
* @background: background colour * @background: background colour
* @depth: how deep to make the pyramid * @depth: how deep to make the pyramid
* @centre: centre the tiles
* *
* Save an image as a set of tiles at various resolutions. By default dzsave * Save an image as a set of tiles at various resolutions. By default dzsave
* uses DeepZoom layout -- use @layout to pick other conventions. * uses DeepZoom layout -- use @layout to pick other conventions.
@ -1286,7 +1384,8 @@ vips_foreign_save_dz_init( VipsForeignSaveDz *dz )
* *
* In Google layout mode, edge tiles are expanded to @tile_size by @tile_size * 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 * pixels. Normally they are filled with white, but you can set another colour
* with @background. * with @background. Images are usually placed at the top-left of the tile,
* but you can have them centred by turning on @centre.
* *
* You can set the size and overlap of tiles with @tile_size and @overlap. * You can set the size and overlap of tiles with @tile_size and @overlap.
* They default to the correct settings for the selected @layout. * They default to the correct settings for the selected @layout.

View File

@ -7,8 +7,9 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
"POT-Creation-Date: 2013-01-15 14:43+0000\n" "product=glib&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2013-01-17 13:26+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -186,7 +187,7 @@ msgstr ""
#: ../libvips/conversion/rot.c:359 ../libvips/conversion/replicate.c:196 #: ../libvips/conversion/rot.c:359 ../libvips/conversion/replicate.c:196
#: ../libvips/conversion/tilecache.c:424 ../libvips/conversion/embed.c:550 #: ../libvips/conversion/tilecache.c:424 ../libvips/conversion/embed.c:550
#: ../libvips/conversion/cache.c:100 ../libvips/conversion/recomb.c:204 #: ../libvips/conversion/cache.c:100 ../libvips/conversion/recomb.c:204
#: ../libvips/conversion/sequential.c:289 ../libvips/foreign/foreign.c:1357 #: ../libvips/conversion/sequential.c:303 ../libvips/foreign/foreign.c:1357
#: ../libvips/resample/resample.c:89 #: ../libvips/resample/resample.c:89
msgid "Input" msgid "Input"
msgstr "" msgstr ""
@ -389,7 +390,7 @@ msgstr ""
#: ../libvips/conversion/extract.c:360 ../libvips/conversion/copy.c:322 #: ../libvips/conversion/extract.c:360 ../libvips/conversion/copy.c:322
#: ../libvips/conversion/rot.c:360 ../libvips/conversion/replicate.c:197 #: ../libvips/conversion/rot.c:360 ../libvips/conversion/replicate.c:197
#: ../libvips/conversion/tilecache.c:425 ../libvips/conversion/embed.c:551 #: ../libvips/conversion/tilecache.c:425 ../libvips/conversion/embed.c:551
#: ../libvips/conversion/cache.c:101 ../libvips/conversion/sequential.c:290 #: ../libvips/conversion/cache.c:101 ../libvips/conversion/sequential.c:304
msgid "Input image" msgid "Input image"
msgstr "" msgstr ""
@ -643,7 +644,7 @@ msgid "Filename to load output profile from"
msgstr "" msgstr ""
#: ../libvips/colour/icc_transform.c:723 ../libvips/colour/icc_transform.c:909 #: ../libvips/colour/icc_transform.c:723 ../libvips/colour/icc_transform.c:909
#: ../libvips/colour/scRGB2sRGB.c:191 ../libvips/foreign/dzsave.c:1204 #: ../libvips/colour/scRGB2sRGB.c:191 ../libvips/foreign/dzsave.c:1215
msgid "Depth" msgid "Depth"
msgstr "" msgstr ""
@ -739,7 +740,7 @@ msgstr ""
#: ../libvips/conversion/flatten.c:382 ../libvips/conversion/join.c:266 #: ../libvips/conversion/flatten.c:382 ../libvips/conversion/join.c:266
#: ../libvips/conversion/insert.c:393 ../libvips/conversion/embed.c:591 #: ../libvips/conversion/insert.c:393 ../libvips/conversion/embed.c:591
#: ../libvips/foreign/dzsave.c:1197 #: ../libvips/foreign/dzsave.c:1208
msgid "Background" msgid "Background"
msgstr "" msgstr ""
@ -1059,14 +1060,14 @@ msgid "cache an image"
msgstr "" msgstr ""
#: ../libvips/conversion/tilecache.c:430 ../libvips/conversion/cache.c:113 #: ../libvips/conversion/tilecache.c:430 ../libvips/conversion/cache.c:113
#: ../libvips/conversion/sequential.c:302 ../libvips/foreign/tiffsave.c:222 #: ../libvips/conversion/sequential.c:316 ../libvips/foreign/tiffsave.c:222
#: ../libvips/foreign/dzsave.c:1229 #: ../libvips/foreign/dzsave.c:1240
msgid "Tile height" msgid "Tile height"
msgstr "" msgstr ""
#: ../libvips/conversion/tilecache.c:431 ../libvips/conversion/cache.c:114 #: ../libvips/conversion/tilecache.c:431 ../libvips/conversion/cache.c:114
#: ../libvips/conversion/sequential.c:303 ../libvips/foreign/tiffsave.c:223 #: ../libvips/conversion/sequential.c:317 ../libvips/foreign/tiffsave.c:223
#: ../libvips/foreign/dzsave.c:1230 #: ../libvips/foreign/dzsave.c:1241
msgid "Tile height in pixels" msgid "Tile height in pixels"
msgstr "" msgstr ""
@ -1091,12 +1092,12 @@ msgid "cache an image as a set of tiles"
msgstr "" msgstr ""
#: ../libvips/conversion/tilecache.c:732 ../libvips/conversion/cache.c:106 #: ../libvips/conversion/tilecache.c:732 ../libvips/conversion/cache.c:106
#: ../libvips/foreign/tiffsave.c:215 ../libvips/foreign/dzsave.c:1222 #: ../libvips/foreign/tiffsave.c:215 ../libvips/foreign/dzsave.c:1233
msgid "Tile width" msgid "Tile width"
msgstr "" msgstr ""
#: ../libvips/conversion/tilecache.c:733 ../libvips/conversion/cache.c:107 #: ../libvips/conversion/tilecache.c:733 ../libvips/conversion/cache.c:107
#: ../libvips/foreign/tiffsave.c:216 ../libvips/foreign/dzsave.c:1223 #: ../libvips/foreign/tiffsave.c:216 ../libvips/foreign/dzsave.c:1234
msgid "Tile width in pixels" msgid "Tile width in pixels"
msgstr "" msgstr ""
@ -1141,7 +1142,7 @@ msgstr ""
msgid "How to generate the extra pixels" msgid "How to generate the extra pixels"
msgstr "" msgstr ""
#: ../libvips/conversion/embed.c:592 ../libvips/foreign/dzsave.c:1198 #: ../libvips/conversion/embed.c:592 ../libvips/foreign/dzsave.c:1209
msgid "Colour for background pixels" msgid "Colour for background pixels"
msgstr "" msgstr ""
@ -1197,15 +1198,15 @@ msgstr ""
msgid "matrix of coefficients" msgid "matrix of coefficients"
msgstr "" msgstr ""
#: ../libvips/conversion/sequential.c:285 #: ../libvips/conversion/sequential.c:299
msgid "check sequential access" msgid "check sequential access"
msgstr "" msgstr ""
#: ../libvips/conversion/sequential.c:295 #: ../libvips/conversion/sequential.c:309
msgid "trace" msgid "trace"
msgstr "" msgstr ""
#: ../libvips/conversion/sequential.c:296 #: ../libvips/conversion/sequential.c:310
msgid "trace pixel requests" msgid "trace pixel requests"
msgstr "" msgstr ""
@ -1494,55 +1495,55 @@ msgstr ""
msgid "Directory \"%s\" exists" msgid "Directory \"%s\" exists"
msgstr "" msgstr ""
#: ../libvips/foreign/dzsave.c:1063 #: ../libvips/foreign/dzsave.c:1074
msgid "overlap must be less than tile width and height" msgid "overlap must be less than tile width and height"
msgstr "" msgstr ""
#: ../libvips/foreign/dzsave.c:1151 #: ../libvips/foreign/dzsave.c:1162
msgid "save image to deep zoom format" msgid "save image to deep zoom format"
msgstr "" msgstr ""
#: ../libvips/foreign/dzsave.c:1161 ../libvips/foreign/dzsave.c:1215 #: ../libvips/foreign/dzsave.c:1172 ../libvips/foreign/dzsave.c:1226
msgid "Base name" msgid "Base name"
msgstr "" msgstr ""
#: ../libvips/foreign/dzsave.c:1162 ../libvips/foreign/dzsave.c:1216 #: ../libvips/foreign/dzsave.c:1173 ../libvips/foreign/dzsave.c:1227
msgid "Base name to save to" msgid "Base name to save to"
msgstr "" msgstr ""
#: ../libvips/foreign/dzsave.c:1168 #: ../libvips/foreign/dzsave.c:1179
msgid "Layout" msgid "Layout"
msgstr "" msgstr ""
#: ../libvips/foreign/dzsave.c:1169 #: ../libvips/foreign/dzsave.c:1180
msgid "Directory layout" msgid "Directory layout"
msgstr "" msgstr ""
#: ../libvips/foreign/dzsave.c:1176 #: ../libvips/foreign/dzsave.c:1187
msgid "suffix" msgid "suffix"
msgstr "" msgstr ""
#: ../libvips/foreign/dzsave.c:1177 #: ../libvips/foreign/dzsave.c:1188
msgid "Filename suffix for tiles" msgid "Filename suffix for tiles"
msgstr "" msgstr ""
#: ../libvips/foreign/dzsave.c:1183 #: ../libvips/foreign/dzsave.c:1194
msgid "Overlap" msgid "Overlap"
msgstr "" msgstr ""
#: ../libvips/foreign/dzsave.c:1184 #: ../libvips/foreign/dzsave.c:1195
msgid "Tile overlap in pixels" msgid "Tile overlap in pixels"
msgstr "" msgstr ""
#: ../libvips/foreign/dzsave.c:1190 #: ../libvips/foreign/dzsave.c:1201
msgid "Tile size" msgid "Tile size"
msgstr "" msgstr ""
#: ../libvips/foreign/dzsave.c:1191 #: ../libvips/foreign/dzsave.c:1202
msgid "Tile size in pixels" msgid "Tile size in pixels"
msgstr "" msgstr ""
#: ../libvips/foreign/dzsave.c:1205 #: ../libvips/foreign/dzsave.c:1216
msgid "Pyramid depth" msgid "Pyramid depth"
msgstr "" msgstr ""
@ -2818,13 +2819,13 @@ msgstr ""
msgid "TB" msgid "TB"
msgstr "" msgstr ""
#: ../libvips/iofuncs/base64.c:170 #: ../libvips/iofuncs/base64.c:168
msgid "too little data" msgid "too little data"
msgstr "" msgstr ""
#. We shouldn't really be used for large amounts of data. #. We shouldn't really be used for large amounts of data.
#. #.
#: ../libvips/iofuncs/base64.c:176 ../libvips/iofuncs/base64.c:241 #: ../libvips/iofuncs/base64.c:174 ../libvips/iofuncs/base64.c:239
msgid "too much data" msgid "too much data"
msgstr "" msgstr ""
@ -3029,16 +3030,16 @@ msgstr ""
msgid "extra tokens after ')'" msgid "extra tokens after ')'"
msgstr "" msgstr ""
#: ../libvips/iofuncs/threadpool.c:197 #: ../libvips/iofuncs/threadpool.c:178
msgid "unable to create thread" msgid "unable to create thread"
msgstr "" msgstr ""
#: ../libvips/iofuncs/threadpool.c:330 #: ../libvips/iofuncs/threadpool.c:311
#, c-format #, c-format
msgid "threads clipped to %d" msgid "threads clipped to %d"
msgstr "" msgstr ""
#: ../libvips/iofuncs/threadpool.c:394 #: ../libvips/iofuncs/threadpool.c:375
msgid "per-thread state for vipsthreadpool" msgid "per-thread state for vipsthreadpool"
msgstr "" msgstr ""
@ -3665,7 +3666,7 @@ msgstr ""
msgid "B-Splines with antialiasing smoothing" msgid "B-Splines with antialiasing smoothing"
msgstr "" msgstr ""
#: ../libvips/resample/nohalo.cpp:1576 #: ../libvips/resample/nohalo.cpp:1580
msgid "Edge sharpening resampler with halo reduction" msgid "Edge sharpening resampler with halo reduction"
msgstr "" msgstr ""