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
- added input space displacement to affine
- VipsArea is threadsafe
- dzsave has a --centre option
31/12/12 started 7.30.7
- better option parsing for "vips", thanks Haida

View File

@ -28,6 +28,8 @@
* - add @background option
* 1/11/12
* - add @depth option
* 21/1/13
* - add @centre option
*/
/*
@ -135,8 +137,9 @@ struct _VipsForeignSaveDz {
int overlap;
int tile_size;
VipsForeignDzLayout layout;
VipsArea *background;
VipsArrayDouble *background;
VipsForeignDzDepth depth;
gboolean centre;
Layer *layer; /* x2 shrink pyr layer */
@ -367,18 +370,39 @@ static int
write_blank( VipsForeignSaveDz *dz )
{
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 );
if( vips_black( &black, dz->tile_size, dz->tile_size,
"bands", 3,
NULL ) )
if( vips_black( &x, dz->tile_size, dz->tile_size, NULL ) )
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 );
}
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 );
}
@ -708,8 +732,9 @@ strip_work( VipsThreadState *state, void *a )
Layer *layer = strip->layer;
VipsForeignSaveDz *dz = layer->dz;
VipsImage *x;
char buf[PATH_MAX];
VipsImage *x;
VipsImage *t;
#ifdef DEBUG
printf( "strip_work\n" );
@ -731,9 +756,7 @@ strip_work( VipsThreadState *state, void *a )
/* Google tiles need to be padded up to tilesize.
*/
if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_GOOGLE ) {
VipsImage *z;
if( vips_embed( x, &z, 0, 0, dz->tile_size, dz->tile_size,
if( vips_embed( x, &t, 0, 0, dz->tile_size, dz->tile_size,
"background", dz->background,
NULL ) ) {
g_object_unref( x );
@ -741,7 +764,35 @@ strip_work( VipsThreadState *state, void *a )
}
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
@ -1091,6 +1142,45 @@ vips_foreign_save_dz_build( VipsObject *object )
build( object ) )
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.
*/
if( !(dz->layer = pyramid_build( dz,
@ -1219,6 +1309,13 @@ vips_foreign_save_dz_class_init( VipsForeignSaveDzClass *class )
VIPS_TYPE_FOREIGN_DZ_DEPTH,
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.
*/
@ -1270,6 +1367,7 @@ vips_foreign_save_dz_init( VipsForeignSaveDz *dz )
* @tile_size; set tile size
* @background: background colour
* @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
* 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
* 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.
* They default to the correct settings for the selected @layout.

View File

@ -7,8 +7,9 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-01-15 14:43+0000\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
"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"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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/tilecache.c:424 ../libvips/conversion/embed.c:550
#: ../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
msgid "Input"
msgstr ""
@ -389,7 +390,7 @@ msgstr ""
#: ../libvips/conversion/extract.c:360 ../libvips/conversion/copy.c:322
#: ../libvips/conversion/rot.c:360 ../libvips/conversion/replicate.c:197
#: ../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"
msgstr ""
@ -643,7 +644,7 @@ msgid "Filename to load output profile from"
msgstr ""
#: ../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"
msgstr ""
@ -739,7 +740,7 @@ msgstr ""
#: ../libvips/conversion/flatten.c:382 ../libvips/conversion/join.c:266
#: ../libvips/conversion/insert.c:393 ../libvips/conversion/embed.c:591
#: ../libvips/foreign/dzsave.c:1197
#: ../libvips/foreign/dzsave.c:1208
msgid "Background"
msgstr ""
@ -1059,14 +1060,14 @@ msgid "cache an image"
msgstr ""
#: ../libvips/conversion/tilecache.c:430 ../libvips/conversion/cache.c:113
#: ../libvips/conversion/sequential.c:302 ../libvips/foreign/tiffsave.c:222
#: ../libvips/foreign/dzsave.c:1229
#: ../libvips/conversion/sequential.c:316 ../libvips/foreign/tiffsave.c:222
#: ../libvips/foreign/dzsave.c:1240
msgid "Tile height"
msgstr ""
#: ../libvips/conversion/tilecache.c:431 ../libvips/conversion/cache.c:114
#: ../libvips/conversion/sequential.c:303 ../libvips/foreign/tiffsave.c:223
#: ../libvips/foreign/dzsave.c:1230
#: ../libvips/conversion/sequential.c:317 ../libvips/foreign/tiffsave.c:223
#: ../libvips/foreign/dzsave.c:1241
msgid "Tile height in pixels"
msgstr ""
@ -1091,12 +1092,12 @@ msgid "cache an image as a set of tiles"
msgstr ""
#: ../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"
msgstr ""
#: ../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"
msgstr ""
@ -1141,7 +1142,7 @@ msgstr ""
msgid "How to generate the extra pixels"
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"
msgstr ""
@ -1197,15 +1198,15 @@ msgstr ""
msgid "matrix of coefficients"
msgstr ""
#: ../libvips/conversion/sequential.c:285
#: ../libvips/conversion/sequential.c:299
msgid "check sequential access"
msgstr ""
#: ../libvips/conversion/sequential.c:295
#: ../libvips/conversion/sequential.c:309
msgid "trace"
msgstr ""
#: ../libvips/conversion/sequential.c:296
#: ../libvips/conversion/sequential.c:310
msgid "trace pixel requests"
msgstr ""
@ -1494,55 +1495,55 @@ msgstr ""
msgid "Directory \"%s\" exists"
msgstr ""
#: ../libvips/foreign/dzsave.c:1063
#: ../libvips/foreign/dzsave.c:1074
msgid "overlap must be less than tile width and height"
msgstr ""
#: ../libvips/foreign/dzsave.c:1151
#: ../libvips/foreign/dzsave.c:1162
msgid "save image to deep zoom format"
msgstr ""
#: ../libvips/foreign/dzsave.c:1161 ../libvips/foreign/dzsave.c:1215
#: ../libvips/foreign/dzsave.c:1172 ../libvips/foreign/dzsave.c:1226
msgid "Base name"
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"
msgstr ""
#: ../libvips/foreign/dzsave.c:1168
#: ../libvips/foreign/dzsave.c:1179
msgid "Layout"
msgstr ""
#: ../libvips/foreign/dzsave.c:1169
#: ../libvips/foreign/dzsave.c:1180
msgid "Directory layout"
msgstr ""
#: ../libvips/foreign/dzsave.c:1176
#: ../libvips/foreign/dzsave.c:1187
msgid "suffix"
msgstr ""
#: ../libvips/foreign/dzsave.c:1177
#: ../libvips/foreign/dzsave.c:1188
msgid "Filename suffix for tiles"
msgstr ""
#: ../libvips/foreign/dzsave.c:1183
#: ../libvips/foreign/dzsave.c:1194
msgid "Overlap"
msgstr ""
#: ../libvips/foreign/dzsave.c:1184
#: ../libvips/foreign/dzsave.c:1195
msgid "Tile overlap in pixels"
msgstr ""
#: ../libvips/foreign/dzsave.c:1190
#: ../libvips/foreign/dzsave.c:1201
msgid "Tile size"
msgstr ""
#: ../libvips/foreign/dzsave.c:1191
#: ../libvips/foreign/dzsave.c:1202
msgid "Tile size in pixels"
msgstr ""
#: ../libvips/foreign/dzsave.c:1205
#: ../libvips/foreign/dzsave.c:1216
msgid "Pyramid depth"
msgstr ""
@ -2818,13 +2819,13 @@ msgstr ""
msgid "TB"
msgstr ""
#: ../libvips/iofuncs/base64.c:170
#: ../libvips/iofuncs/base64.c:168
msgid "too little data"
msgstr ""
#. 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"
msgstr ""
@ -3029,16 +3030,16 @@ msgstr ""
msgid "extra tokens after ')'"
msgstr ""
#: ../libvips/iofuncs/threadpool.c:197
#: ../libvips/iofuncs/threadpool.c:178
msgid "unable to create thread"
msgstr ""
#: ../libvips/iofuncs/threadpool.c:330
#: ../libvips/iofuncs/threadpool.c:311
#, c-format
msgid "threads clipped to %d"
msgstr ""
#: ../libvips/iofuncs/threadpool.c:394
#: ../libvips/iofuncs/threadpool.c:375
msgid "per-thread state for vipsthreadpool"
msgstr ""
@ -3665,7 +3666,7 @@ msgstr ""
msgid "B-Splines with antialiasing smoothing"
msgstr ""
#: ../libvips/resample/nohalo.cpp:1576
#: ../libvips/resample/nohalo.cpp:1580
msgid "Edge sharpening resampler with halo reduction"
msgstr ""