done! but needs some tests

This commit is contained in:
John Cupitt 2017-05-04 14:54:49 +01:00
parent 3900cebdf8
commit 260180197d
7 changed files with 62 additions and 37 deletions

View File

@ -4,6 +4,7 @@
constant image constant image
- add new_from_image() to Python as well - add new_from_image() to Python as well
- slight change to cpp new_from_image() to match py/C behaviour - slight change to cpp new_from_image() to match py/C behaviour
- add FORCE resize mode to break aspect ratio
23/4/17 started 8.5.5 23/4/17 started 8.5.5
- doc polishing - doc polishing

4
TODO
View File

@ -1,4 +1,6 @@
- cpp bandjoin should use bandjoin_const() where possibel ... currently - need tests for new thumbnail mode
- cpp bandjoin should use bandjoin_const() where possible ... currently
uses new_from_image uses new_from_image
- not sure about utf8 error messages on win - not sure about utf8 error messages on win

View File

@ -102,7 +102,7 @@ example:
$ vips shrink fred.png jim.png 10 10 $ vips shrink fred.png jim.png 10 10
``` ```
meaning shrink `fred.png` by a factor of 10 in both axies and write as meaning shrink `fred.png` by a factor of 10 in both axes and write as
`jim.png`. `jim.png`.
You can imagine this operation running without needing `fred.png` to be You can imagine this operation running without needing `fred.png` to be

View File

@ -831,6 +831,7 @@ vips_size_get_type( void )
{VIPS_SIZE_BOTH, "VIPS_SIZE_BOTH", "both"}, {VIPS_SIZE_BOTH, "VIPS_SIZE_BOTH", "both"},
{VIPS_SIZE_UP, "VIPS_SIZE_UP", "up"}, {VIPS_SIZE_UP, "VIPS_SIZE_UP", "up"},
{VIPS_SIZE_DOWN, "VIPS_SIZE_DOWN", "down"}, {VIPS_SIZE_DOWN, "VIPS_SIZE_DOWN", "down"},
{VIPS_SIZE_FORCE, "VIPS_SIZE_FORCE", "force"},
{VIPS_SIZE_LAST, "VIPS_SIZE_LAST", "last"}, {VIPS_SIZE_LAST, "VIPS_SIZE_LAST", "last"},
{0, NULL, NULL} {0, NULL, NULL}
}; };

View File

@ -5,6 +5,8 @@
* - from vipsthumbnail.c * - from vipsthumbnail.c
* 6/1/17 * 6/1/17
* - add @size parameter * - add @size parameter
* 4/5/17
* - add FORCE
*/ */
/* /*
@ -156,17 +158,17 @@ vips_thumbnail_calculate_shrink( VipsThumbnail *thumbnail,
* In crop mode, we aim to fill the bounding box, so we must use the * In crop mode, we aim to fill the bounding box, so we must use the
* smaller axis. * smaller axis.
*/ */
double horizontal = (double) width / thumbnail->width; *hshrink = (double) width / thumbnail->width;
double vertical = (double) height / thumbnail->height; *vshrink = (double) height / thumbnail->height;
if( thumbnail->crop != VIPS_INTERESTING_NONE ) { if( thumbnail->crop != VIPS_INTERESTING_NONE ) {
if( horizontal < vertical ) if( *hshrink < *vshrink )
direction = VIPS_DIRECTION_HORIZONTAL; direction = VIPS_DIRECTION_HORIZONTAL;
else else
direction = VIPS_DIRECTION_VERTICAL; direction = VIPS_DIRECTION_VERTICAL;
} }
else { else {
if( horizontal < vertical ) if( *hshrink < *vshrink )
direction = VIPS_DIRECTION_VERTICAL; direction = VIPS_DIRECTION_VERTICAL;
else else
direction = VIPS_DIRECTION_HORIZONTAL; direction = VIPS_DIRECTION_HORIZONTAL;
@ -174,24 +176,27 @@ vips_thumbnail_calculate_shrink( VipsThumbnail *thumbnail,
if( thumbnail->size != VIPS_SIZE_FORCE ) { if( thumbnail->size != VIPS_SIZE_FORCE ) {
if( direction == VIPS_DIRECTION_HORIZONTAL ) if( direction == VIPS_DIRECTION_HORIZONTAL )
vertical = horizontal; *vshrink = *hshrink;
else else
horizontal = vertical; *hshrink = *vshrink;
} }
else if( thumbnail->size == VIPS_SIZE_UP )
shrink = VIPS_MIN( 1, shrink );
else if( thumbnail->size == VIPS_SIZE_DOWN )
shrink = VIPS_MAX( 1, shrink );
if( thumbnail->size == VIPS_SIZE_UP ) {
*hshrink = VIPS_MIN( 1, *hshrink );
*vshrink = VIPS_MIN( 1, *vshrink );
}
else if( thumbnail->size == VIPS_SIZE_DOWN ) {
*hshrink = VIPS_MAX( 1, *hshrink );
*vshrink = VIPS_MAX( 1, *vshrink );
}
} }
/* Just the common part of the shrink: the bit by which both axies must be /* Just the common part of the shrink: the bit by which both axes must be
* shrunk. * shrunk.
*/ */
static double static double
vips_thumbnail_calculate_common_shrink( VipsThumbnail *thumbnail, vips_thumbnail_calculate_common_shrink( VipsThumbnail *thumbnail,
int input_width, int input_height ) int width, int height )
{ {
double hshrink; double hshrink;
double vshrink; double vshrink;
@ -244,7 +249,7 @@ vips_thumbnail_open( VipsThumbnail *thumbnail )
VipsThumbnailClass *class = VIPS_THUMBNAIL_GET_CLASS( thumbnail ); VipsThumbnailClass *class = VIPS_THUMBNAIL_GET_CLASS( thumbnail );
VipsImage *im; VipsImage *im;
int shrink; double shrink;
double scale; double scale;
if( class->get_info( thumbnail ) ) if( class->get_info( thumbnail ) )
@ -253,25 +258,26 @@ vips_thumbnail_open( VipsThumbnail *thumbnail )
g_info( "input size is %d x %d", g_info( "input size is %d x %d",
thumbnail->input_width, thumbnail->input_height ); thumbnail->input_width, thumbnail->input_height );
shrink = 1; shrink = 1.0;
scale = 1.0; scale = 1.0;
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 %g 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 / shrink = vips_thumbnail_calculate_common_shrink( thumbnail,
vips_thumbnail_calculate_common_shrink( thumbnail, thumbnail->input_width, thumbnail->input_height );
width, height ); scale = 1.0 / shrink;
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_common_shrink( thumbnail, shrink = vips_thumbnail_calculate_common_shrink( thumbnail,
width, height ); thumbnail->input_width, thumbnail->input_height );
g_info( "loading webp with factor %g pre-shrink", shrink ); g_info( "loading webp with factor %g pre-shrink", shrink );
} }
@ -393,12 +399,13 @@ vips_thumbnail_build( VipsObject *object )
in = t[3]; in = t[3];
} }
shrink = vips_thumbnail_calculate_shrink( thumbnail, vips_thumbnail_calculate_shrink( thumbnail,
in->Xsize, in->Ysize ); in->Xsize, in->Ysize, &hshrink, &vshrink );
/* Use centre convention to better match imagemagick. /* Use centre convention to better match imagemagick.
*/ */
if( vips_resize( in, &t[4], 1.0 / shrink, if( vips_resize( in, &t[4], 1.0 / hshrink,
"vscale", 1.0 / vshrink,
"centre", TRUE, "centre", TRUE,
NULL ) ) NULL ) )
return( -1 ); return( -1 );
@ -659,8 +666,6 @@ vips_thumbnail_file_open( VipsThumbnail *thumbnail, int shrink, double scale )
{ {
VipsThumbnailFile *file = (VipsThumbnailFile *) thumbnail; VipsThumbnailFile *file = (VipsThumbnailFile *) thumbnail;
/* We can't use UNBUFERRED safely on very-many-core systems.
*/
if( shrink != 1 ) if( shrink != 1 )
return( vips_image_new_from_file( file->filename, return( vips_image_new_from_file( file->filename,
"access", VIPS_ACCESS_SEQUENTIAL, "access", VIPS_ACCESS_SEQUENTIAL,

View File

@ -94,7 +94,7 @@ option.
.TP .TP
.B -c, --crop .B -c, --crop
Crop the output image down. The image is shrunk so as to completely fill the Crop the output image down. The image is shrunk so as to completely fill the
bounding box in both axies, then any excess is cropped off. bounding box in both axes, then any excess is cropped off.
.TP .TP
.B -d, --delete .B -d, --delete

View File

@ -90,6 +90,8 @@
* 6/1/17 * 6/1/17
* - fancy geometry strings * - fancy geometry strings
* - support VipSize restrictions * - support VipSize restrictions
* 4/5/17
* - add ! geo modifier
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -333,7 +335,7 @@ thumbnail_parse_geometry( const char *geometry )
p++; p++;
} }
/* Get the final < or >. /* Get the final <>!
*/ */
while( isspace( *p ) ) while( isspace( *p ) )
p++; p++;
@ -341,6 +343,8 @@ thumbnail_parse_geometry( const char *geometry )
size_restriction = VIPS_SIZE_UP; size_restriction = VIPS_SIZE_UP;
else if( *p == '>' ) else if( *p == '>' )
size_restriction = VIPS_SIZE_DOWN; size_restriction = VIPS_SIZE_DOWN;
else if( *p == '!' )
size_restriction = VIPS_SIZE_FORCE;
else if( *p != '\0' || else if( *p != '\0' ||
(thumbnail_width == VIPS_MAX_COORD && (thumbnail_width == VIPS_MAX_COORD &&
thumbnail_height == VIPS_MAX_COORD) ) { thumbnail_height == VIPS_MAX_COORD) ) {
@ -348,18 +352,30 @@ thumbnail_parse_geometry( const char *geometry )
return( -1 ); return( -1 );
} }
/* If --crop is set, both width and height must be specified, /* If force is set and one of width or height isn't set, copy from the
* since we'll need a complete bounding box to fill. * one that is.
*/ */
if( (crop_image || smartcrop_image) && if( size_restriction == VIPS_SIZE_FORCE ) {
(thumbnail_width == VIPS_MAX_COORD || if( thumbnail_width == VIPS_MAX_COORD )
thumbnail_height == VIPS_MAX_COORD) ) { thumbnail_width = thumbnail_height;
vips_error( "thumbnail", if( thumbnail_height == VIPS_MAX_COORD )
"both width and height must be given if " thumbnail_height = thumbnail_width;
"crop is enabled" );
return( -1 );
} }
/* If --crop is set or force is set, both width and height must be
* specified, since we'll need a complete bounding box to fill.
*/
if( crop_image ||
smartcrop_image ||
size_restriction == VIPS_SIZE_FORCE )
if( thumbnail_width == VIPS_MAX_COORD ||
thumbnail_height == VIPS_MAX_COORD ) {
vips_error( "thumbnail",
"both width and height must be given if "
"crop is enabled" );
return( -1 );
}
return( 0 ); return( 0 );
} }