add an intent option to thumbnail

"intent" lets you set the rendering intent for any ICC conversions --
the default is the (more correct) relative, but "perceptual" can look
better

see https://github.com/jcupitt/libvips/issues/714
This commit is contained in:
John Cupitt 2017-08-30 16:34:46 +01:00
parent 820c279697
commit 5a37d3e809
3 changed files with 41 additions and 1 deletions

View File

@ -14,6 +14,7 @@
- remove lcms1 support, it had bitrotted
- `join` tagged as seq
- support tiffsave_buffer for pyramids, thanks bubba
- thumbnail and vipsthumbnail have an option for rendering intent, thanks kleisauke
29/8/17 started 8.5.9
- make --fail stop jpeg read on any libjpeg warning, thanks @mceachen

View File

@ -9,6 +9,8 @@
* - add FORCE
* 29/5/17
* - don't cache (thanks tomasc)
* 30/8/17
* - add intent option, thanks kleisauke
*/
/*
@ -81,6 +83,7 @@ typedef struct _VipsThumbnail {
gboolean linear;
char *export_profile;
char *import_profile;
VipsIntent intent;
/* Set by subclasses to the input image.
*/
@ -375,6 +378,7 @@ vips_thumbnail_build( VipsObject *object )
if( vips_icc_import( in, &t[1],
"input_profile", thumbnail->import_profile,
"embedded", TRUE,
"intent", thumbnail->intent,
"pcs", VIPS_PCS_XYZ,
NULL ) )
return( -1 );
@ -442,6 +446,7 @@ vips_thumbnail_build( VipsObject *object )
g_info( "exporting to device space with a profile" );
if( vips_icc_export( in, &t[7],
"output_profile", thumbnail->export_profile,
"intent", thumbnail->intent,
NULL ) )
return( -1 );
in = t[7];
@ -470,6 +475,7 @@ vips_thumbnail_build( VipsObject *object )
if( vips_icc_transform( in, &t[7],
thumbnail->export_profile,
"intent", thumbnail->intent,
"embedded", TRUE,
NULL ) ) {
g_warning( _( "unable to import with "
@ -489,6 +495,7 @@ vips_thumbnail_build( VipsObject *object )
if( vips_icc_transform( in, &t[7],
thumbnail->export_profile,
"input_profile", thumbnail->import_profile,
"intent", thumbnail->intent,
"embedded", FALSE,
NULL ) )
return( -1 );
@ -630,6 +637,13 @@ vips_thumbnail_class_init( VipsThumbnailClass *class )
G_STRUCT_OFFSET( VipsThumbnail, export_profile ),
NULL );
VIPS_ARG_ENUM( class, "intent", 120,
_( "Intent" ),
_( "Rendering intent" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsThumbnail, intent ),
VIPS_TYPE_INTENT, VIPS_INTENT_RELATIVE );
}
static void
@ -638,6 +652,7 @@ vips_thumbnail_init( VipsThumbnail *thumbnail )
thumbnail->width = 1;
thumbnail->height = 1;
thumbnail->auto_rotate = TRUE;
thumbnail->intent = VIPS_INTENT_RELATIVE;
}
typedef struct _VipsThumbnailFile {
@ -745,6 +760,7 @@ vips_thumbnail_file_init( VipsThumbnailFile *file )
* * @linear: %gboolean, perform shrink in linear light
* * @import_profile: %gchararray, fallback import ICC profile
* * @export_profile: %gchararray, export ICC profile
* * @intent: #VipsIntent, rendering intent
*
* Make a thumbnail from a file. Shrinking is done in three stages: using any
* shrink-on-load features available in the file import library, using a block
@ -786,6 +802,9 @@ vips_thumbnail_file_init( VipsThumbnailFile *file )
* input image has no ICC profile, or if the profile embedded in the
* input image is broken.
*
* Use @intent to set the rendering intent for any ICC transform. The default
* is #VIPS_INTENT_RELATIVE.
*
* See also: vips_thumbnail_buffer().
*
* Returns: 0 on success, -1 on error.
@ -917,6 +936,7 @@ vips_thumbnail_buffer_init( VipsThumbnailBuffer *buffer )
* * @linear: %gboolean, perform shrink in linear light
* * @import_profile: %gchararray, fallback import ICC profile
* * @export_profile: %gchararray, export ICC profile
* * @intent: #VipsIntent, rendering intent
*
* Exacty as vips_thumbnail(), but read from a memory buffer.
*
@ -1031,6 +1051,7 @@ vips_thumbnail_image_init( VipsThumbnailImage *image )
* * @linear: %gboolean, perform shrink in linear light
* * @import_profile: %gchararray, fallback import ICC profile
* * @export_profile: %gchararray, export ICC profile
* * @intent: #VipsIntent, rendering intent
*
* Exacty as vips_thumbnail(), but read from an existing image.
*

View File

@ -92,6 +92,8 @@
* - support VipSize restrictions
* 4/5/17
* - add ! geo modifier
* 30/8/17
* - add --intent
*/
#ifdef HAVE_CONFIG_H
@ -125,6 +127,7 @@ static gboolean linear_processing = FALSE;
static gboolean crop_image = FALSE;
static char *smartcrop_image = NULL;
static gboolean rotate_image = FALSE;
static char *thumbnail_intent = NULL;
/* Deprecated and unused.
*/
@ -162,6 +165,10 @@ static GOptionEntry options[] = {
G_OPTION_ARG_STRING, &smartcrop_image,
N_( "shrink and crop to fill SIZE using STRATEGY" ),
N_( "STRATEGY" ) },
{ "intent", 'n', 0,
G_OPTION_ARG_STRING, &thumbnail_intent,
N_( "ICC transform with INTENT" ),
N_( "INTENT" ) },
{ "rotate", 't', 0,
G_OPTION_ARG_NONE, &rotate_image,
N_( "auto-rotate" ), NULL },
@ -245,18 +252,28 @@ thumbnail_process( VipsObject *process, const char *filename )
{
VipsInteresting interesting;
VipsImage *image;
VipsIntent intent;
interesting = VIPS_INTERESTING_NONE;
if( crop_image )
interesting = VIPS_INTERESTING_CENTRE;
if( smartcrop_image ) {
int n;
if( (n = vips_enum_from_nick( "vipsthumbnail",
VIPS_TYPE_INTERESTING, smartcrop_image )) < 0 )
return( -1 );
interesting = n;
}
intent = VIPS_INTENT_RELATIVE;
if( thumbnail_intent ) {
int n;
if( (n = vips_enum_from_nick( "vipsthumbnail",
VIPS_TYPE_INTENT, thumbnail_intent )) < 0 )
return( -1 );
intent = n;
}
if( vips_thumbnail( filename, &image, thumbnail_width,
"height", thumbnail_height,
@ -266,6 +283,7 @@ thumbnail_process( VipsObject *process, const char *filename )
"linear", linear_processing,
"import_profile", import_profile,
"export_profile", export_profile,
"intent", intent,
NULL ) )
return( -1 );