add an anti-alias filter to vipsthumbnail
vipsthumbnail blurs slightly between shrink and affine, if the affine will be doing a large shrink
This commit is contained in:
parent
385b2ea5fa
commit
ed3c56fcbf
|
@ -6,8 +6,9 @@
|
||||||
- argh fix affine, again, there were sometimes black bars with nohalo and the
|
- argh fix affine, again, there were sometimes black bars with nohalo and the
|
||||||
vips8 interface
|
vips8 interface
|
||||||
- pngsave in interlaced mode makes a copy of the image, so it's always seq
|
- pngsave in interlaced mode makes a copy of the image, so it's always seq
|
||||||
- vipsthumbnail shrinks to 1/2 window_size: faster and better quality
|
- vipsthumbnail shrinks to 1/2 window_size
|
||||||
- vipsthumbnail defaults to bicubic + nosharpen
|
- vipsthumbnail has an anti-alias filter between shrink and affine
|
||||||
|
- vipsthumbnail defaults to bicubic
|
||||||
- better rounding behaviour for fixed-point bicubic reduces noise
|
- better rounding behaviour for fixed-point bicubic reduces noise
|
||||||
- fix pngload with libpng >=1.6.11
|
- fix pngload with libpng >=1.6.11
|
||||||
- fix colour for openslide read associated
|
- fix colour for openslide read associated
|
||||||
|
|
|
@ -52,9 +52,10 @@
|
||||||
* 30/6/14
|
* 30/6/14
|
||||||
* - fix interlaced thumbnail output, thanks lovell
|
* - fix interlaced thumbnail output, thanks lovell
|
||||||
* 3/8/14
|
* 3/8/14
|
||||||
* - box shrink less, use interpolator more, if the window_size is large
|
* - box shrink less, use interpolator more, if window_size is large
|
||||||
* enough
|
* enough
|
||||||
* - default to bicubic + nosharpen if bicubic is available
|
* - default to bicubic if available
|
||||||
|
* - add an anti-alias filter between shrink and affine
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -72,7 +73,7 @@
|
||||||
|
|
||||||
#define ORIENTATION ("exif-ifd0-Orientation")
|
#define ORIENTATION ("exif-ifd0-Orientation")
|
||||||
|
|
||||||
/* Default settings. We change the default to bicubic + nosharpen in main() if
|
/* Default settings. We change the default to bicubic in main() if
|
||||||
* this vips has been compiled with bicubic support.
|
* this vips has been compiled with bicubic support.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -391,12 +392,15 @@ thumbnail_shrink( VipsObject *process, VipsImage *in,
|
||||||
VipsImage **t = (VipsImage **) vips_object_local_array( process, 10 );
|
VipsImage **t = (VipsImage **) vips_object_local_array( process, 10 );
|
||||||
VipsInterpretation interpretation = linear_processing ?
|
VipsInterpretation interpretation = linear_processing ?
|
||||||
VIPS_INTERPRETATION_XYZ : VIPS_INTERPRETATION_sRGB;
|
VIPS_INTERPRETATION_XYZ : VIPS_INTERPRETATION_sRGB;
|
||||||
|
const int window_size =
|
||||||
|
interp ? vips_interpolate_get_window_size( interp ) : 2;
|
||||||
|
|
||||||
int shrink;
|
int shrink;
|
||||||
double residual;
|
double residual;
|
||||||
int tile_width;
|
int tile_width;
|
||||||
int tile_height;
|
int tile_height;
|
||||||
int nlines;
|
int nlines;
|
||||||
|
double sigma;
|
||||||
|
|
||||||
/* RAD needs special unpacking.
|
/* RAD needs special unpacking.
|
||||||
*/
|
*/
|
||||||
|
@ -474,6 +478,7 @@ thumbnail_shrink( VipsObject *process, VipsImage *in,
|
||||||
* has been used ... but it never will, since thread1 will block on
|
* has been used ... but it never will, since thread1 will block on
|
||||||
* this cache lock.
|
* this cache lock.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vips_get_tile_size( in,
|
vips_get_tile_size( in,
|
||||||
&tile_width, &tile_height, &nlines );
|
&tile_width, &tile_height, &nlines );
|
||||||
if( vips_tilecache( in, &t[4],
|
if( vips_tilecache( in, &t[4],
|
||||||
|
@ -482,12 +487,38 @@ thumbnail_shrink( VipsObject *process, VipsImage *in,
|
||||||
"max_tiles", (nlines * 2) / 10,
|
"max_tiles", (nlines * 2) / 10,
|
||||||
"access", VIPS_ACCESS_SEQUENTIAL,
|
"access", VIPS_ACCESS_SEQUENTIAL,
|
||||||
"threaded", TRUE,
|
"threaded", TRUE,
|
||||||
NULL ) ||
|
NULL ) )
|
||||||
vips_affine( t[4], &t[5], residual, 0, 0, residual,
|
|
||||||
"interpolate", interp,
|
|
||||||
NULL ) )
|
|
||||||
return( NULL );
|
return( NULL );
|
||||||
in = t[5];
|
in = t[4];
|
||||||
|
|
||||||
|
/* If the final affine will be doing a large downsample, we can get
|
||||||
|
* nasty aliasing on hard edges. Blur before affine to smooth this out.
|
||||||
|
*
|
||||||
|
* Don't blur for very small shrinks, blur with radius 1 for x1.5
|
||||||
|
* shrinks, blur radius 2 for x2.5 shrinks and above, etc.
|
||||||
|
*/
|
||||||
|
sigma = ((1.0 / residual) - 0.5) / 1.5;
|
||||||
|
if( sigma > 0.1 ) {
|
||||||
|
if( vips_gaussmat( &t[9], sigma, 0.2,
|
||||||
|
"separable", TRUE,
|
||||||
|
"integer", TRUE,
|
||||||
|
NULL ) ||
|
||||||
|
vips_convsep( in, &t[5], t[9], NULL ) )
|
||||||
|
return( NULL );
|
||||||
|
vips_info( "vipsthumbnail", "anti-alias, sigma %g",
|
||||||
|
sigma );
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "anti-alias blur matrix is:\n" );
|
||||||
|
vips_matrixprint( t[9], NULL );
|
||||||
|
#endif /*DEBUG*/
|
||||||
|
in = t[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
if( vips_affine( in, &t[6], residual, 0, 0, residual,
|
||||||
|
"interpolate", interp,
|
||||||
|
NULL ) )
|
||||||
|
return( NULL );
|
||||||
|
in = t[6];
|
||||||
|
|
||||||
vips_info( "vipsthumbnail", "residual scale by %g", residual );
|
vips_info( "vipsthumbnail", "residual scale by %g", residual );
|
||||||
vips_info( "vipsthumbnail", "%s interpolation",
|
vips_info( "vipsthumbnail", "%s interpolation",
|
||||||
|
@ -511,10 +542,10 @@ thumbnail_shrink( VipsObject *process, VipsImage *in,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
vips_info( "vipsthumbnail", "converting to sRGB" );
|
vips_info( "vipsthumbnail", "converting to sRGB" );
|
||||||
if( vips_colourspace( in, &t[6],
|
if( vips_colourspace( in, &t[7],
|
||||||
VIPS_INTERPRETATION_sRGB, NULL ) )
|
VIPS_INTERPRETATION_sRGB, NULL ) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
in = t[6];
|
in = t[7];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( export_profile &&
|
else if( export_profile &&
|
||||||
|
@ -530,13 +561,13 @@ thumbnail_shrink( VipsObject *process, VipsImage *in,
|
||||||
vips_info( "vipsthumbnail",
|
vips_info( "vipsthumbnail",
|
||||||
"exporting with profile %s", export_profile );
|
"exporting with profile %s", export_profile );
|
||||||
|
|
||||||
if( vips_icc_transform( in, &t[6], export_profile,
|
if( vips_icc_transform( in, &t[7], export_profile,
|
||||||
"input_profile", import_profile,
|
"input_profile", import_profile,
|
||||||
"embedded", TRUE,
|
"embedded", TRUE,
|
||||||
NULL ) )
|
NULL ) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
in = t[6];
|
in = t[7];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we are upsampling, don't sharpen, since nearest looks dumb
|
/* If we are upsampling, don't sharpen, since nearest looks dumb
|
||||||
|
@ -687,13 +718,11 @@ main( int argc, char **argv )
|
||||||
textdomain( GETTEXT_PACKAGE );
|
textdomain( GETTEXT_PACKAGE );
|
||||||
setlocale( LC_ALL, "" );
|
setlocale( LC_ALL, "" );
|
||||||
|
|
||||||
/* Does this vips have bicubic? Default to that + nosharpen if it
|
/* Does this vips have bicubic? Default to that if it
|
||||||
* does.
|
* does.
|
||||||
*/
|
*/
|
||||||
if( vips_type_find( "VipsInterpolate", "bicubic" ) ) {
|
if( vips_type_find( "VipsInterpolate", "bicubic" ) )
|
||||||
interpolator = "bicubic";
|
interpolator = "bicubic";
|
||||||
convolution_mask = "none";
|
|
||||||
}
|
|
||||||
|
|
||||||
context = g_option_context_new( _( "- thumbnail generator" ) );
|
context = g_option_context_new( _( "- thumbnail generator" ) );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue