Skip to content

Latest commit

 

History

History
251 lines (181 loc) · 15.9 KB

introduction-for-converting.md

File metadata and controls

251 lines (181 loc) · 15.9 KB

Introduction to converting with WebPConvert

The library is able to convert images to webp using a variety of methods (gd, imagick, vips etc.), which we call "converters". A converter is called like this:

use WebPConvert\Convert\Converters\Gd;

Gd::convert($source, $destination, $options=[], $logger=null);

All converters comes with requirements. For example, the Gd converter requires that Gd is installed and compiled with webp support. The cloud converters requires an api key. In case the conversion fails, an exception is thrown.

Insights to the process

If $logger is supplied, the converter will log the details of how the conversion process went to that logger. You can for example use the supplied EchoLogger to print directly to screen or the BufferLogger to collect the log entries. Here is a simple example which prints the process to screen:

use WebPConvert\Convert\Converters\Gd;
use WebPConvert\Loggers\EchoLogger;

Gd::convert($source, $destination, $options=[], new EchoLogger());

It will output something like this:

GD Version: 2.2.5
image is true color
Quality set to same as source: 61

Converted image in 20 ms, reducing file size with 34% (went from 12 kb to 8 kb)

The stack converter

When your software is going to be installed on a variety of systems which you do not control, you can try the converters one at the time until success. The converters has been designed to exit quickly when system requirements are not met. To make this task easy, a Stack converter has been created.

The stack converter has two special options:

option description
converters (array) Converters to try (ids or class names, in case you have your own custom converter)
converter-options (array) Extra options for specific converters.

Alternatively to the converter-options array, you can simply prefix options with the converter id.

I recommend leave the converters array at the default unless you have strong reasons not to. Otherwise you might miss out when new converters are added.

Example:

use WebPConvert\Convert\Converters\Stack;

Stack::convert($source, $destination, $options = [    

    // PS: only set converters if you have strong reasons to do so
    'converters' => [
        'cwebp', 'vips', 'imagick', 'gmagick', 'imagemagick', 'graphicsmagick', 'wpc', 'ewww', 'gd'
    ],

    // Any available options can be set here, they dribble down to all converters.
    'metadata' => 'all',

    // To override for specific converter, you can prefix with converter id:
    'cwebp-metadata' => 'exif',

    // This can for example be used for setting ewww api key:
    'ewww-api-key' => 'your-ewww-api-key-here',

    // As an alternative to prefixing, you can use "converter-options" to set a whole bunch of overrides in one go:
    'converter-options' => [        
        'wpc' => [
            'crypt-api-key-in-transfer' => true
            'api-key' => 'my dog is white',
            'api-url' => 'https://example.com/wpc.php',
            'api-version' => 1,
        ],
    ],
], $logger=null);

Note: As an alternative to setting the third party credentials in the options, you can set them through constants or environment variables ("WEBPCONVERT_EWWW_API_KEY", "WEBPCONVERT_WPC_API_KEY", "WEBPCONVERT_WPC_API_URL"). Paths to binaries can also be set like that (it is rarely needed to do this): "WEBPCONVERT_CWEBP_PATH", "WEBPCONVERT_GRAPHICSMAGICK_PATH" and WEBPCONVERT_IMAGEMAGICK_PATH"

To set an environment variable in Apache, you can add a line like this in your .htaccess or vhost configuration:

# Set ewww api key for WebP Convert
SetEnv WEBPCONVERT_EWWW_API_KEY yourVerySecretApiKeyGoesHere

# Set custom path to imagick for WebP Convert
SetEnv WEBPCONVERT_IMAGEMAGICK_PATH /usr/local/bin/magick

To set a constant:

define('WEBPCONVERT_IMAGEMAGICK_PATH', '/usr/local/bin/magick');

Configuring the options

Preventing unnecessarily high quality setting for low quality jpegs

Q: What do you get if you convert a low quality jpeg (ie q=50) into a high quality webp (ie q=90) ?
A: You maintain the low quality, but you get a large file`

What should we have done instead? We should have converted with a quality around 50. Of course, quality is still low - we cannot fix that - but it will not be less, and the converted file will be much smaller.

As unnecessary large conversions are rarely desirable, this library per default limits the quality setting so it does not exceed that of the source. This functionality requires that either imagemagick, graphicsmagick or imagick is installed (not necessarily compiled with webp support). When they are, all converters will have the "auto-limit" functionality. Otherwise, only wpc will support it (provided that one of these libraries is installed on the server of the cloud service).

How much can be gained? A lot! The following low quality (q=50) jpeg weighs 54 kb. If this is converted to webp with quality=80, the size of the converted file is 52kb - almost no reduction! With auto-limit, the quality of the webp will be set to 50, and the size will be 34kb. Visually, the results are indistinguable.

A low quality jpeg

Auto selecting between lossless/lossy encoding

WebP files can be encoded using either lossless or lossy encoding. The JPEG format is lossy and the PNG is lossless. However, this does not mean that you necessarily get the best conversion by always encoding JPEG to lossy and PNG to lossless. With JPEGs it is often the case, as they are usually pictures and pictures usually best encoded as lossy. With PNG it is however a different story, as you often can get a better compression using lossy encoding, also when using high quality level of say 85, which should be enough for the web.

As unnecessary large conversions are rarely desirable, this library per default tries to convert images using both lossy and lossless encoding and automatically selects the smallest. This is controlled using the encoding option, which per default is "auto", but can also be set to "lossy" or "lossless".

As an example, the following PNG (231 kb) will be compressed to 156 kb when converting to lossless webp. But when converting to lossy (quality: 85), it is compressed to merely 68 kb - less than half. (in case you are confused about the combination of lossy and transparency: Yes, you can have both at the same time with webp).

Dice

Unless you changed the near-lossless option described below, the choice is actually between lossy and near-lossless.

Note that gd and ewww does not support this feature. gd can only produce lossy, and will simply do that. ewww can not be configured to use a certain encoding, but automatically chooses lossless encoding for PNGs and lossy for JPEGs.

Near-lossless

cwebp and vips supports "near-lossless" mode. Near lossless produces a webp with lossless encoding but adjusts pixel values to help compressibility. The result is a smaller file. The price is described as a minimal impact on the visual quality.

As unnecessary large conversions are rarely desirable, this library per default sets near-lossless to 60. To disable near-lossless, set it to 100.

When compressing the image above (231 kb) to lossless, it compressed to 156 kb when near-lossless is set to 100. Setting near-lossless to 60 gets the size down to 110 kb while still looking great.

You can read more about the near-lossless mode here

Alpha-quality

All converters, except gd and ewww supports "alpha-quality" option. This allows lossy compressing of the alpha channel.

As unnecessary large conversions are rarely desirable, this library per default sets alpha-quality to 85. Set it to 100 to achieve lossless compression of alhpa.

Btw, the image above gets compressed to 68 kb with alpha quality set to 100. Surprisingly, it gets slightly larger (70 kb) with alpha quality set to 85. Setting alpha quality to 50 gets it down to merely 35 kb - about half - while still looking great.

You can read more about the alpha-quality option here and here

Sharp YUV

libwebp has an overlooked option which improves accuracy for RGB to YUV mapping at the price for longer conversion time. You can control it with the new 'sharp-yuv' option (introduced in webp-convert 2.6.0). Read an appraisal of the option here.

Tip: don't set quality too high...

Q: What do you get if you convert an excessively high quality jpeg into an excessively high quality webp?
A: An excessively big file

The size of a webp file grows enormously with the quality setting. For the web however, a quality above 75 is rarely needed. For this reason the library has a per default sets the quality to 75 for jpegs.

So, how much can be gained? A lot! The following excessively high quality jpeg (q=100) weighs 146 kb. Converting it to webp with quality=100 results in a 99kb image. Converting it to quality=85 results in a 40kb image.

A (too) high quality jpeg

PNG og JPEG-specific options.

To have options depending on the image type of the source, you can use the png and jpeg keys.

The following options mimics the default behaviour (version 2.0 - 2.5):

$options = [
    'png' => [
        'encoding' => 'auto',    /* Try both lossy and lossless and pick smallest */
        'near-lossless' => 60,   /* The level of near-lossless image preprocessing (when trying lossless) */
        'quality' => 85,         /* Quality when trying lossy. It is set high because pngs is often selected to ensure high quality */
        'sharp-yuv' => true,
    ],
    'jpeg' => [
        'encoding' => 'auto',     /* If you are worried about the longer conversion time, you could set it to "lossy" instead (lossy will often be smaller than lossless for jpegs) */
        'quality' => 'auto',      /* Set to same as jpeg (requires imagick or gmagick extension, not necessarily compiled with webp) */
        'max-quality' => 80,      /* Only relevant if quality is set to "auto" */
        'default-quality' => 75,  /* Fallback quality if quality detection isnt working */
        'sharp-yuv' => true,
    ]
];

PS: From version 2.6 on, you should use the new "auto-limit" option instead of setting quality to "auto".

The following options mimics the default behaviour (version 2.6 and forth):

$options = [
    'png' => [
        'encoding' => 'auto',    /* Try both lossy and lossless and pick smallest */
        'near-lossless' => 60,   /* The level of near-lossless image preprocessing (when trying lossless) */
        'quality' => 85,         /* Quality when trying lossy. It is set high because pngs is often selected to ensure high quality */
        'sharp-yuv' => true,
    ],
    'jpeg' => [
        'encoding' => 'auto',     /* If you are worried about the longer conversion time, you could set it to "lossy" instead (lossy will often be smaller than lossless for jpegs) */
        'quality' => 75,          /* Quality when trying lossy. It is set a bit lower for jpeg than png */
        'auto-limit' => true,     /* Prevents using a higher quality than that of the source (requires imagick or gmagick extension, not necessarily compiled with webp) */
        'sharp-yuv' => true,
    ]
];

The png and jpeg options can hold any other option - also the converter specific options. A use case could for example be to use different converters for png and jpeg:

$options = [
    'png' => [
        'converters' => ['ewww'],
    ],
    'jpeg' => [
        'converters' => ['gd'],
    ]
];

Available options

All available options are documented here.

Here is a quick overview of the few ones discussed here.

Version 2.0 - 2.5

Option Default (jpeg) Default (png) Description
quality "auto" 85 See the "Auto quality" section above.
max-quality 85 85 Only relevant for jpegs and when quality is set to "auto".
default-quality 75 85
metadata "none" "none" Valid values: "all", "none", "exif", "icc", "xmp".

Note: Currently only cwebp supports all values. gd will always remove all metadata. ewww, imagick and gmagick can either strip all, or keep all (they will keep all, unless metadata is set to none)
encoding "auto" "auto" See the "Auto selecting between lossless/lossy encoding" section above
jpeg - - Array of options which will be merged into the other options when source is a JPEG
png - - Array of options which will be merged into the other options when source is a PNG
skip false false If true, conversion will be skipped (ie for skipping png conversion for some converters)

Version > 2.6

Option Default (jpeg) Default (png) Description
quality 75 85 Quality for lossy encoding
auto-limit true true Only relevant for jpegs and lossy encoding
metadata "none" "none" Valid values: "all", "none", "exif", "icc", "xmp".

Note: Currently only cwebp supports all values. gd will always remove all metadata. ewww, imagick and gmagick can either strip all, or keep all (they will keep all, unless metadata is set to none)
encoding "auto" "auto" See the "Auto selecting between lossless/lossy encoding" section above
jpeg - - Array of options which will be merged into the other options when source is a JPEG
png - - Array of options which will be merged into the other options when source is a PNG
skip false false If true, conversion will be skipped (ie for skipping png conversion for some converters)

More info

  • The complete api is available here
  • The converters are described in more detail here (for 1.3.9): docs/v1.3/converting/converters.md.
  • On the github wiki you can find installation instructions for imagick with webp, gd with webp, etc.
  • This document is a newly written introduction to the convert api, which has been created as part of the 2.0 release. The old introduction, which was made for 1.3 is available here: docs/converting/v1.3/convert.md.