try to improve vips_resize() quality

small improvements to vips_resize() quality:

* turn down the anti-alias filter a little so we don't smudge out texture
* don't do the final sharpening pass if we skipped the anti-alias filter
* fix a >/>= mixup which meant we didn't sharpen for small resizes
This commit is contained in:
John Cupitt 2015-11-19 15:22:23 +00:00
parent 40173838d1
commit 8506ff13a6
4 changed files with 17 additions and 12 deletions

View File

@ -12,6 +12,7 @@
- sizealike / formatalike / bandsalike elide completely if they can for - sizealike / formatalike / bandsalike elide completely if they can for
a x2 saving in C stack use in many cases a x2 saving in C stack use in many cases
- added vips_mapim() ... resample with an index image, plus test - added vips_mapim() ... resample with an index image, plus test
- try to improve vips_resize() quality a little more
7/5/15 started 8.1.1 7/5/15 started 8.1.1
- oop, vips-8.0 wrapper script should be vips-8.1, thanks Danilo - oop, vips-8.0 wrapper script should be vips-8.1, thanks Danilo

3
TODO
View File

@ -6,9 +6,6 @@
- vips_resize() should not use the anti-alias filter if vips_shrink() has
not been called, ie. for shrinks < 2 or so
- still not happy about float->int mask conversion in im_vips2mask.c - still not happy about float->int mask conversion in im_vips2mask.c
- looks like we have a race in tiled threadcache? see - looks like we have a race in tiled threadcache? see

View File

@ -75,6 +75,7 @@ G_DEFINE_TYPE( VipsResize, vips_resize, VIPS_TYPE_RESAMPLE );
static int static int
vips_resize_build( VipsObject *object ) vips_resize_build( VipsObject *object )
{ {
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
VipsResample *resample = VIPS_RESAMPLE( object ); VipsResample *resample = VIPS_RESAMPLE( object );
VipsResize *resize = (VipsResize *) object; VipsResize *resize = (VipsResize *) object;
@ -87,6 +88,7 @@ vips_resize_build( VipsObject *object )
int int_shrink_width; int int_shrink_width;
double residual; double residual;
double sigma; double sigma;
gboolean anti_alias;
if( VIPS_OBJECT_CLASS( vips_resize_parent_class )->build( object ) ) if( VIPS_OBJECT_CLASS( vips_resize_parent_class )->build( object ) )
return( -1 ); return( -1 );
@ -129,6 +131,7 @@ vips_resize_build( VipsObject *object )
/* A copy for enlarge resize. /* A copy for enlarge resize.
*/ */
vips_info( class->nickname, "box shrink by x %d", int_shrink );
if( vips_shrink( in, &t[0], int_shrink, int_shrink, NULL ) ) if( vips_shrink( in, &t[0], int_shrink, int_shrink, NULL ) )
return( -1 ); return( -1 );
in = t[0]; in = t[0];
@ -189,14 +192,19 @@ vips_resize_build( VipsObject *object )
* Don't blur for very small shrinks, blur with radius 1 for x1.5 * 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. * shrinks, blur radius 2 for x2.5 shrinks and above, etc.
*/ */
sigma = ((1.0 / residual) - 0.5) / 1.5; sigma = ((1.0 / residual) - 0.5) / 2.0;
if( residual < 1.0 && anti_alias = residual < 1.0 && sigma > 0.1;
sigma > 0.1 ) { if( anti_alias ) {
vips_info( class->nickname, "anti-alias sigma %g", sigma );
if( vips_gaussblur( in, &t[2], sigma, NULL ) ) if( vips_gaussblur( in, &t[2], sigma, NULL ) )
return( -1 ); return( -1 );
in = t[2]; in = t[2];
} }
vips_info( class->nickname, "residual affine %g", residual );
vips_info( class->nickname, "%s interpolation",
VIPS_OBJECT_GET_CLASS( resize->interpolate )->nickname );
if( vips_affine( in, &t[3], residual, 0, 0, residual, if( vips_affine( in, &t[3], residual, 0, 0, residual,
"interpolate", resize->interpolate, "interpolate", resize->interpolate,
"idx", resize->idx, "idx", resize->idx,
@ -205,9 +213,12 @@ vips_resize_build( VipsObject *object )
return( -1 ); return( -1 );
in = t[3]; in = t[3];
/* If we are upsampling, don't sharpen. /* If we are upsampling, don't sharpen. Also don't sharpen if we
* skipped the anti-alias filter.
*/ */
if( int_shrink > 1 ) { if( int_shrink >= 1 &&
anti_alias ) {
vips_info( class->nickname, "final sharpen" );
t[5] = vips_image_new_matrixv( 3, 3, t[5] = vips_image_new_matrixv( 3, 3,
-1.0, -1.0, -1.0, -1.0, -1.0, -1.0,
-1.0, 32.0, -1.0, -1.0, 32.0, -1.0,

View File

@ -439,10 +439,6 @@ thumbnail_shrink( VipsObject *process, VipsImage *in,
shrink = calculate_shrink( in ); shrink = calculate_shrink( in );
vips_info( "vipsthumbnail", "shrink by %g", shrink );
vips_info( "vipsthumbnail", "%s interpolation",
VIPS_OBJECT_GET_CLASS( interp )->nickname );
if( vips_resize( in, &t[4], 1.0 / shrink, if( vips_resize( in, &t[4], 1.0 / shrink,
"interpolate", interp, "interpolate", interp,
NULL ) ) NULL ) )