start adding FORCE
start experimental implementation see https://github.com/jcupitt/libvips/issues/648
This commit is contained in:
parent
1504fb0249
commit
3900cebdf8
@ -51,6 +51,7 @@ typedef enum {
|
|||||||
VIPS_SIZE_BOTH,
|
VIPS_SIZE_BOTH,
|
||||||
VIPS_SIZE_UP,
|
VIPS_SIZE_UP,
|
||||||
VIPS_SIZE_DOWN,
|
VIPS_SIZE_DOWN,
|
||||||
|
VIPS_SIZE_FORCE,
|
||||||
VIPS_SIZE_LAST
|
VIPS_SIZE_LAST
|
||||||
} VipsSize;
|
} VipsSize;
|
||||||
|
|
||||||
|
@ -87,9 +87,10 @@
|
|||||||
* @VIPS_SIZE_BOTH: size both up and down
|
* @VIPS_SIZE_BOTH: size both up and down
|
||||||
* @VIPS_SIZE_UP: only upsize
|
* @VIPS_SIZE_UP: only upsize
|
||||||
* @VIPS_SIZE_DOWN: only downsize
|
* @VIPS_SIZE_DOWN: only downsize
|
||||||
|
* @VIPS_SIZE_FORCE: force size, that is, break aspect ratio
|
||||||
*
|
*
|
||||||
* Controls whether an operation should upsize, downsize, or both up and
|
* Controls whether an operation should upsize, downsize, both up and
|
||||||
* downsize.
|
* downsize, or force a size.
|
||||||
*
|
*
|
||||||
* See also: vips_thumbnail().
|
* See also: vips_thumbnail().
|
||||||
*/
|
*/
|
||||||
|
@ -136,9 +136,9 @@ vips_thumbnail_finalize( GObject *gobject )
|
|||||||
/* Calculate the shrink factor, taking into account auto-rotate, the fit mode,
|
/* Calculate the shrink factor, taking into account auto-rotate, the fit mode,
|
||||||
* and so on.
|
* and so on.
|
||||||
*/
|
*/
|
||||||
static double
|
static void
|
||||||
vips_thumbnail_calculate_shrink( VipsThumbnail *thumbnail,
|
vips_thumbnail_calculate_shrink( VipsThumbnail *thumbnail,
|
||||||
int input_width, int input_height )
|
int input_width, int input_height, double *hshrink, double *vshrink )
|
||||||
{
|
{
|
||||||
gboolean rotate =
|
gboolean rotate =
|
||||||
thumbnail->angle == VIPS_ANGLE_D90 ||
|
thumbnail->angle == VIPS_ANGLE_D90 ||
|
||||||
@ -149,7 +149,6 @@ vips_thumbnail_calculate_shrink( VipsThumbnail *thumbnail,
|
|||||||
input_width : input_height;
|
input_width : input_height;
|
||||||
|
|
||||||
VipsDirection direction;
|
VipsDirection direction;
|
||||||
double shrink;
|
|
||||||
|
|
||||||
/* 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.
|
||||||
@ -173,17 +172,34 @@ vips_thumbnail_calculate_shrink( VipsThumbnail *thumbnail,
|
|||||||
direction = VIPS_DIRECTION_HORIZONTAL;
|
direction = VIPS_DIRECTION_HORIZONTAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
shrink = direction == VIPS_DIRECTION_HORIZONTAL ?
|
if( thumbnail->size != VIPS_SIZE_FORCE ) {
|
||||||
horizontal : vertical;
|
if( direction == VIPS_DIRECTION_HORIZONTAL )
|
||||||
|
vertical = horizontal;
|
||||||
/* Restrict to only upsize, only downsize, or both.
|
else
|
||||||
*/
|
horizontal = vertical;
|
||||||
if( thumbnail->size == VIPS_SIZE_UP )
|
}
|
||||||
|
else if( thumbnail->size == VIPS_SIZE_UP )
|
||||||
shrink = VIPS_MIN( 1, shrink );
|
shrink = VIPS_MIN( 1, shrink );
|
||||||
if( thumbnail->size == VIPS_SIZE_DOWN )
|
else if( thumbnail->size == VIPS_SIZE_DOWN )
|
||||||
shrink = VIPS_MAX( 1, shrink );
|
shrink = VIPS_MAX( 1, shrink );
|
||||||
|
|
||||||
return( shrink );
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Just the common part of the shrink: the bit by which both axies must be
|
||||||
|
* shrunk.
|
||||||
|
*/
|
||||||
|
static double
|
||||||
|
vips_thumbnail_calculate_common_shrink( VipsThumbnail *thumbnail,
|
||||||
|
int input_width, int input_height )
|
||||||
|
{
|
||||||
|
double hshrink;
|
||||||
|
double vshrink;
|
||||||
|
|
||||||
|
vips_thumbnail_calculate_shrink( thumbnail, width, height,
|
||||||
|
&hshrink, &vshrink );
|
||||||
|
|
||||||
|
return( VIPS_MIN( hshrink, vshrink ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the best jpeg preload shrink.
|
/* Find the best jpeg preload shrink.
|
||||||
@ -191,8 +207,8 @@ vips_thumbnail_calculate_shrink( VipsThumbnail *thumbnail,
|
|||||||
static int
|
static int
|
||||||
vips_thumbnail_find_jpegshrink( VipsThumbnail *thumbnail, int width, int height )
|
vips_thumbnail_find_jpegshrink( VipsThumbnail *thumbnail, int width, int height )
|
||||||
{
|
{
|
||||||
double shrink =
|
double shrink = vips_thumbnail_calculate_common_shrink( thumbnail,
|
||||||
vips_thumbnail_calculate_shrink( thumbnail, width, height );
|
width, height );
|
||||||
|
|
||||||
/* We can't use pre-shrunk images in linear mode. libjpeg shrinks in Y
|
/* We can't use pre-shrunk images in linear mode. libjpeg shrinks in Y
|
||||||
* (of YCbCR), not linear space.
|
* (of YCbCR), not linear space.
|
||||||
@ -243,18 +259,21 @@ vips_thumbnail_open( VipsThumbnail *thumbnail )
|
|||||||
if( vips_isprefix( "VipsForeignLoadJpeg", thumbnail->loader ) ) {
|
if( vips_isprefix( "VipsForeignLoadJpeg", thumbnail->loader ) ) {
|
||||||
shrink = vips_thumbnail_find_jpegshrink( thumbnail,
|
shrink = vips_thumbnail_find_jpegshrink( thumbnail,
|
||||||
thumbnail->input_width, thumbnail->input_height );
|
thumbnail->input_width, thumbnail->input_height );
|
||||||
g_info( "loading jpeg with factor %d pre-shrink", shrink );
|
g_info( "loading jpeg with factor %g pre-shrink", shrink );
|
||||||
}
|
}
|
||||||
else if( vips_isprefix( "VipsForeignLoadPdf", thumbnail->loader ) ||
|
else if( vips_isprefix( "VipsForeignLoadPdf", thumbnail->loader ) ||
|
||||||
vips_isprefix( "VipsForeignLoadSvg", thumbnail->loader ) ) {
|
vips_isprefix( "VipsForeignLoadSvg", thumbnail->loader ) ) {
|
||||||
scale = 1.0 / vips_thumbnail_calculate_shrink( thumbnail,
|
scale = 1.0 /
|
||||||
thumbnail->input_width, thumbnail->input_height );
|
vips_thumbnail_calculate_common_shrink( thumbnail,
|
||||||
|
width, height );
|
||||||
|
|
||||||
g_info( "loading PDF/SVG with factor %g pre-scale", scale );
|
g_info( "loading PDF/SVG with factor %g pre-scale", scale );
|
||||||
}
|
}
|
||||||
else if( vips_isprefix( "VipsForeignLoadWebp", thumbnail->loader ) ) {
|
else if( vips_isprefix( "VipsForeignLoadWebp", thumbnail->loader ) ) {
|
||||||
shrink = vips_thumbnail_calculate_shrink( thumbnail,
|
shrink = vips_thumbnail_calculate_common_shrink( thumbnail,
|
||||||
thumbnail->input_width, thumbnail->input_height );
|
width, height );
|
||||||
g_info( "loading webp with factor %d pre-shrink", shrink );
|
|
||||||
|
g_info( "loading webp with factor %g pre-shrink", shrink );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !(im = class->open( thumbnail, shrink, scale )) )
|
if( !(im = class->open( thumbnail, shrink, scale )) )
|
||||||
@ -272,7 +291,8 @@ vips_thumbnail_build( VipsObject *object )
|
|||||||
VIPS_INTERPRETATION_scRGB : VIPS_INTERPRETATION_sRGB;
|
VIPS_INTERPRETATION_scRGB : VIPS_INTERPRETATION_sRGB;
|
||||||
|
|
||||||
VipsImage *in;
|
VipsImage *in;
|
||||||
double shrink;
|
double hshrink;
|
||||||
|
double vshrink;
|
||||||
|
|
||||||
/* TRUE if we've done the import of an ICC transform and still need to
|
/* TRUE if we've done the import of an ICC transform and still need to
|
||||||
* export.
|
* export.
|
||||||
@ -719,12 +739,15 @@ vips_thumbnail_file_init( VipsThumbnailFile *file )
|
|||||||
* @height rectangle, with any excess cropped away. See vips_smartcrop() for
|
* @height rectangle, with any excess cropped away. See vips_smartcrop() for
|
||||||
* details on the cropping strategy.
|
* details on the cropping strategy.
|
||||||
*
|
*
|
||||||
* Normally the operation will upsize or downsize as required. If @size is set
|
* Normally the operation will upsize or downsize as required to fit the image
|
||||||
|
* inside or outside the target size. If @size is set
|
||||||
* to #VIPS_SIZE_UP, the operation will only upsize and will just
|
* to #VIPS_SIZE_UP, the operation will only upsize and will just
|
||||||
* copy if asked to downsize.
|
* copy if asked to downsize.
|
||||||
* If @size is set
|
* If @size is set
|
||||||
* to #VIPS_SIZE_DOWN, the operation will only downsize and will just
|
* to #VIPS_SIZE_DOWN, the operation will only downsize and will just
|
||||||
* copy if asked to upsize.
|
* copy if asked to upsize.
|
||||||
|
* If @size is #VIPS_SIZE_FORCE, the image aspect ratio will be broken and the
|
||||||
|
* image will be forced to fit the target.
|
||||||
*
|
*
|
||||||
* Normally any orientation tags on the input image (such as EXIF tags) are
|
* Normally any orientation tags on the input image (such as EXIF tags) are
|
||||||
* interpreted to rotate the image upright. If you set @auto_rotate to %FALSE,
|
* interpreted to rotate the image upright. If you set @auto_rotate to %FALSE,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user