Add alpha_q(uality) webpsave option, fix Q init
This allows to control the fidelity of the alpha channel by allowing webp to reduce the number of palette entries from 256 at alpha_q=100 to 2 at alpha_q=0. This is most useful with cutout pictures where something like alpha_q=30 or around 8 levels is usually sufficient for smooth outlines. For some reason webp->Q was intiailized to 80 even though the Q option and libwebp use 75 by default. This was never used, so it's just to avoid confusion about what default is used.
This commit is contained in:
parent
c107066c4e
commit
0a25f6efca
@ -2462,6 +2462,7 @@ vips_webpload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
||||
* @preset: #VipsForeignWebpPreset choose lossy compression preset
|
||||
* @smart_subsample: enables high quality chroma subsampling
|
||||
* @near_lossless: use preprocessing in lossless mode (controlled by Q)
|
||||
* @alpha_q: set alpha quality in lossless mode
|
||||
*
|
||||
* See also: vips_webpload(), vips_image_write_to_file().
|
||||
*
|
||||
@ -2494,6 +2495,7 @@ vips_webpsave( VipsImage *in, const char *filename, ... )
|
||||
* @preset: #VipsForeignWebpPreset choose lossy compression preset
|
||||
* @smart_subsample: enables high quality chroma subsampling
|
||||
* @near_lossless: use preprocessing in lossless mode (controlled by Q)
|
||||
* @alpha_q: set alpha quality in lossless mode
|
||||
*
|
||||
* See also: vips_webpsave().
|
||||
*
|
||||
|
@ -85,7 +85,8 @@ get_preset( VipsForeignWebpPreset preset )
|
||||
static int
|
||||
write_webp( WebPPicture *pic, VipsImage *in,
|
||||
int Q, gboolean lossless, VipsForeignWebpPreset preset,
|
||||
gboolean smart_subsample, gboolean near_lossless )
|
||||
gboolean smart_subsample, gboolean near_lossless,
|
||||
int alpha_q )
|
||||
{
|
||||
VipsImage *memory;
|
||||
WebPConfig config;
|
||||
@ -102,6 +103,7 @@ write_webp( WebPPicture *pic, VipsImage *in,
|
||||
config.preprocessing |= 4;
|
||||
if( near_lossless )
|
||||
config.near_lossless = Q;
|
||||
config.alpha_quality = alpha_q;
|
||||
|
||||
if( !WebPValidateConfig(&config) ) {
|
||||
vips_error( "vips2webp",
|
||||
@ -147,7 +149,8 @@ write_webp( WebPPicture *pic, VipsImage *in,
|
||||
int
|
||||
vips__webp_write_file( VipsImage *in, const char *filename,
|
||||
int Q, gboolean lossless, VipsForeignWebpPreset preset,
|
||||
gboolean smart_subsample, gboolean near_lossless )
|
||||
gboolean smart_subsample, gboolean near_lossless,
|
||||
int alpha_q )
|
||||
{
|
||||
WebPPicture pic;
|
||||
WebPMemoryWriter writer;
|
||||
@ -164,7 +167,7 @@ vips__webp_write_file( VipsImage *in, const char *filename,
|
||||
pic.custom_ptr = &writer;
|
||||
|
||||
if( write_webp( &pic, in, Q, lossless, preset, smart_subsample,
|
||||
near_lossless ) ) {
|
||||
near_lossless, alpha_q ) ) {
|
||||
WebPPictureFree( &pic );
|
||||
WebPMemoryWriterClear( &writer );
|
||||
return -1;
|
||||
@ -192,7 +195,8 @@ vips__webp_write_file( VipsImage *in, const char *filename,
|
||||
int
|
||||
vips__webp_write_buffer( VipsImage *in, void **obuf, size_t *olen,
|
||||
int Q, gboolean lossless, VipsForeignWebpPreset preset,
|
||||
gboolean smart_subsample, gboolean near_lossless )
|
||||
gboolean smart_subsample, gboolean near_lossless,
|
||||
int alpha_q )
|
||||
{
|
||||
WebPPicture pic;
|
||||
WebPMemoryWriter writer;
|
||||
@ -209,7 +213,7 @@ vips__webp_write_buffer( VipsImage *in, void **obuf, size_t *olen,
|
||||
pic.custom_ptr = &writer;
|
||||
|
||||
if( write_webp( &pic, in, Q, lossless, preset, smart_subsample,
|
||||
near_lossless) ) {
|
||||
near_lossless, alpha_q ) ) {
|
||||
WebPPictureFree( &pic );
|
||||
WebPMemoryWriterClear( &writer );
|
||||
return -1;
|
||||
|
@ -50,10 +50,12 @@ int vips__webp_read_buffer( const void *buf, size_t len,
|
||||
|
||||
int vips__webp_write_file( VipsImage *out, const char *filename,
|
||||
int Q, gboolean lossless, VipsForeignWebpPreset preset,
|
||||
gboolean smart_subsample, gboolean near_lossless );
|
||||
gboolean smart_subsample, gboolean near_lossless,
|
||||
int alpha_q );
|
||||
int vips__webp_write_buffer( VipsImage *out, void **buf, size_t *len,
|
||||
int Q, gboolean lossless, VipsForeignWebpPreset preset,
|
||||
gboolean smart_subsample, gboolean near_lossless );
|
||||
gboolean smart_subsample, gboolean near_lossless,
|
||||
int alpha_q );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -72,6 +72,10 @@ typedef struct _VipsForeignSaveWebp {
|
||||
*/
|
||||
gboolean near_lossless;
|
||||
|
||||
/* Alpha quality.
|
||||
*/
|
||||
int alpha_q;
|
||||
|
||||
} VipsForeignSaveWebp;
|
||||
|
||||
typedef VipsForeignSaveClass VipsForeignSaveWebpClass;
|
||||
@ -143,12 +147,19 @@ vips_foreign_save_webp_class_init( VipsForeignSaveWebpClass *class )
|
||||
G_STRUCT_OFFSET( VipsForeignSaveWebp, near_lossless ),
|
||||
FALSE );
|
||||
|
||||
VIPS_ARG_INT( class, "alpha_q", 15,
|
||||
_( "Alpha quality" ),
|
||||
_( "Change alpha plane fidelity for lossy compression" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignSaveWebp, alpha_q ),
|
||||
0, 100, 100 );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_save_webp_init( VipsForeignSaveWebp *webp )
|
||||
{
|
||||
webp->Q = 80;
|
||||
webp->Q = 75;
|
||||
}
|
||||
|
||||
typedef struct _VipsForeignSaveWebpFile {
|
||||
@ -178,7 +189,8 @@ vips_foreign_save_webp_file_build( VipsObject *object )
|
||||
|
||||
if( vips__webp_write_file( save->ready, file->filename,
|
||||
webp->Q, webp->lossless, webp->preset,
|
||||
webp->smart_subsample, webp->near_lossless ) )
|
||||
webp->smart_subsample, webp->near_lossless,
|
||||
webp->alpha_q ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -241,7 +253,8 @@ vips_foreign_save_webp_buffer_build( VipsObject *object )
|
||||
|
||||
if( vips__webp_write_buffer( save->ready, &obuf, &olen,
|
||||
webp->Q, webp->lossless, webp->preset,
|
||||
webp->smart_subsample, webp->near_lossless ) )
|
||||
webp->smart_subsample, webp->near_lossless,
|
||||
webp->alpha_q ) )
|
||||
return( -1 );
|
||||
|
||||
blob = vips_blob_new( (VipsCallbackFn) vips_free, obuf, olen );
|
||||
@ -303,7 +316,8 @@ vips_foreign_save_webp_mime_build( VipsObject *object )
|
||||
|
||||
if( vips__webp_write_buffer( save->ready, &obuf, &olen,
|
||||
webp->Q, webp->lossless, webp->preset,
|
||||
webp->smart_subsample, webp->near_lossless ) )
|
||||
webp->smart_subsample, webp->near_lossless,
|
||||
webp->alpha_q ) )
|
||||
return( -1 );
|
||||
|
||||
printf( "Content-length: %zu\r\n", olen );
|
||||
|
Loading…
x
Reference in New Issue
Block a user