allow mixed zoom and shrink in resize

vips_resize() now allows >1 on one axis, <1 on the other ... previously,
although you could have non-square ratios, you couldn't mix zoom and
shrink
This commit is contained in:
John Cupitt 2016-05-01 12:03:13 +01:00
parent 73080bb4a5
commit c2d1de9a26
3 changed files with 42 additions and 22 deletions

View File

@ -3,6 +3,7 @@
- export C++ operator overloads for MSVC linking [Lovell] - export C++ operator overloads for MSVC linking [Lovell]
- fix magickload @page with GraphicsMagick - fix magickload @page with GraphicsMagick
- add giflib5 support - add giflib5 support
- allow resize >1 on one axis, <1 on the other
29/1/16 started 8.3 29/1/16 started 8.3
- add vips_reduce*() ... a fast path for affine downsize - add vips_reduce*() ... a fast path for affine downsize

View File

@ -10,6 +10,8 @@
* - shrink more affine less, now we have better anti-alias settings * - shrink more affine less, now we have better anti-alias settings
* 10/3/16 * 10/3/16
* - revise again, using new vips_reduce() code * - revise again, using new vips_reduce() code
* 1/5/16
* - allow >1 on one axis, <1 on the other
*/ */
/* /*
@ -132,15 +134,20 @@ vips_resize_build( VipsObject *object )
else else
int_vshrink = int_hshrink; int_vshrink = int_hshrink;
if( int_hshrink > 1 || if( int_vshrink > 1 ) {
int_vshrink > 1 ) { vips_info( class->nickname, "shrinkv by %d", int_vshrink );
vips_info( class->nickname, "box shrink by %d x %d", if( vips_shrinkv( in, &t[0], int_vshrink, NULL ) )
int_hshrink, int_vshrink );
if( vips_shrink( in, &t[0], int_hshrink, int_vshrink, NULL ) )
return( -1 ); return( -1 );
in = t[0]; in = t[0];
} }
if( int_hshrink > 1 ) {
vips_info( class->nickname, "shrinkh by %d", int_hshrink );
if( vips_shrinkh( in, &t[1], int_hshrink, NULL ) )
return( -1 );
in = t[1];
}
/* Do we need a further size adjustment? It's the difference /* Do we need a further size adjustment? It's the difference
* between our target size and the size we have after vips_shrink(). * between our target size and the size we have after vips_shrink().
* *
@ -195,30 +202,43 @@ vips_resize_build( VipsObject *object )
in = t[6]; in = t[6];
} }
/* Any downsizing. /* Any residual downsizing.
*/ */
if( hresidual < 1.0 || if( vresidual < 1.0 ) {
vresidual < 1.0 ) { vips_info( class->nickname, "residual reducev by %g",
vips_info( class->nickname, "residual reduce by %g x %g", vresidual );
hresidual, vresidual ); if( vips_reducev( in, &t[2], 1.0 / vresidual, NULL ) )
if( vips_reduce( in, &t[2],
1.0 / hresidual, 1.0 / vresidual, NULL ) )
return( -1 ); return( -1 );
in = t[2]; in = t[2];
} }
if( hresidual < 1.0 ) {
vips_info( class->nickname, "residual reduceh by %g",
hresidual );
if( vips_reduceh( in, &t[3], 1.0 / hresidual, NULL ) )
return( -1 );
in = t[3];
}
/* Any upsizing. /* Any upsizing.
*/ */
if( hresidual > 1.0 || if( hresidual > 1.0 ) {
vresidual > 1.0 ) { vips_info( class->nickname, "residual scaleh %g",
vips_info( class->nickname, "residual scale %g x %g", hresidual );
hresidual, vresidual ); if( vips_affine( in, &t[4], hresidual, 0.0, 0.0, 1.0,
if( vips_affine( in, &t[3], hresidual, 0, 0, vresidual,
"interpolate", vips_interpolate_nearest_static(), "interpolate", vips_interpolate_nearest_static(),
NULL ) ) NULL ) )
return( -1 ); return( -1 );
in = t[3]; in = t[4];
}
if( vresidual > 1.0 ) {
vips_info( class->nickname, "residual scalev %g", vresidual );
if( vips_affine( in, &t[5], 1.0, 0.0, 0.0, vresidual,
"interpolate", vips_interpolate_nearest_static(),
NULL ) )
return( -1 );
in = t[5];
} }
if( vips_image_write( in, resample->out ) ) if( vips_image_write( in, resample->out ) )

View File

@ -99,13 +99,12 @@ vips_shrink_build( VipsObject *object )
yresidual = (double) target_height / t[1]->Ysize; yresidual = (double) target_height / t[1]->Ysize;
if( vips_affine( t[1], &t[2], if( vips_affine( t[1], &t[2],
xresidual, 0.0, 0.0, yresidual, NULL ) || xresidual, 0.0, 0.0, yresidual, NULL ) ||
vips_image_write( t[2], resample->out ) ) vips_image_write( t[2], resample->out ) )
return( -1 ); return( -1 );
} }
else { else {
if( vips_shrinkv( resample->in, &t[0], if( vips_shrinkv( resample->in, &t[0], shrink->yshrink, NULL ) ||
shrink->yshrink, NULL ) ||
vips_shrinkh( t[0], &t[1], shrink->xshrink, NULL ) || vips_shrinkh( t[0], &t[1], shrink->xshrink, NULL ) ||
vips_image_write( t[1], resample->out ) ) vips_image_write( t[1], resample->out ) )
return( -1 ); return( -1 );