better shrink selection in vipsthumbnail

see:

https://github.com/jcupitt/libvips/issues/126

https://github.com/lovell/sharp/issues/41#issuecomment-44429413

thanks @ttback
This commit is contained in:
John Cupitt 2014-06-09 14:44:06 +01:00
parent 0f33123dbf
commit a6ec270adf

View File

@ -177,6 +177,8 @@ calculate_shrink( VipsImage *im, double *residual )
int width = rotate_image && rotate ? im->Ysize : im->Xsize; int width = rotate_image && rotate ? im->Ysize : im->Xsize;
int height = rotate_image && rotate ? im->Xsize : im->Ysize; int height = rotate_image && rotate ? im->Xsize : im->Ysize;
VipsDirection direction;
/* Calculate the horizontal and vertical shrink we'd need to fit the /* Calculate the horizontal and vertical shrink we'd need to fit the
* image to the bounding box, and pick the biggest. * image to the bounding box, and pick the biggest.
* *
@ -185,9 +187,22 @@ calculate_shrink( VipsImage *im, double *residual )
*/ */
double horizontal = (double) width / thumbnail_width; double horizontal = (double) width / thumbnail_width;
double vertical = (double) height / thumbnail_height; double vertical = (double) height / thumbnail_height;
double factor = crop_image ?
VIPS_MIN( horizontal, vertical ) : if( crop_image ) {
VIPS_MAX( horizontal, vertical ); if( horizontal < vertical )
direction = VIPS_DIRECTION_HORIZONTAL;
else
direction = VIPS_DIRECTION_VERTICAL;
}
else {
if( horizontal < vertical )
direction = VIPS_DIRECTION_VERTICAL;
else
direction = VIPS_DIRECTION_HORIZONTAL;
}
double factor = direction == VIPS_DIRECTION_HORIZONTAL ?
horizontal : vertical;
/* If the shrink factor is <= 1.0, we need to zoom rather than shrink. /* If the shrink factor is <= 1.0, we need to zoom rather than shrink.
* Just set the factor to 1 in this case. * Just set the factor to 1 in this case.
@ -198,20 +213,24 @@ calculate_shrink( VipsImage *im, double *residual )
*/ */
int shrink = floor( factor2 ); int shrink = floor( factor2 );
if( residual ) { if( residual &&
/* Size after int shrink. We have to try with both axes since direction == VIPS_DIRECTION_HORIZONTAL ) {
* if they are very different sizes we'll see different /* Size after int shrink.
* rounding errors.
*/ */
int iwidth = width / shrink; int iwidth = width / shrink;
int iheight = height / shrink;
/* Therefore residual scale factor is. /* Therefore residual scale factor is.
*/ */
double hresidual = (width / factor) / iwidth; double hresidual = (width / factor) / iwidth;
*residual = hresidual;
}
else if( residual &&
direction == VIPS_DIRECTION_VERTICAL ) {
int iheight = height / shrink;
double vresidual = (height / factor) / iheight; double vresidual = (height / factor) / iheight;
*residual = VIPS_MAX( hresidual, vresidual ); *residual = vresidual;
} }
return( shrink ); return( shrink );