Add X13 WebP module for image conversion to next-generation formats

- Implemented the main module class with essential properties and methods.
- Added translation support for various user interface strings.
- Created XML configuration file for module versioning.
- Ensured compatibility with different PHP versions and PrestaShop versions.
This commit is contained in:
2025-10-16 21:30:24 +02:00
parent d220e35c31
commit 3b29a79921
235 changed files with 40220 additions and 189 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@@ -0,0 +1,248 @@
# Stack converter
The stack converter is a mechanism for trying all available converters until success. Well, the default is to try all converters, but this can be configured.
When calling `WebPConvert::convert($source, $destination, $options);`, you are actually invoking the stack converter.
## Passing options down to the individual converters
Any option that you pass to the Stack converter will be passed on to the individual converters. For example, setting options to the following will set the metadata option on all converters:
```php
$options = [
'metadata' => 'all',
];
```
If you need the option to be different for a single converter there are several ways to do it:
#### 1. Prefixing
Options prefixed with a converter id are only effective for that converter, and overrides the non-prefixed option.
Ie, the following will set "metadata" to "all" for all converters, except *cwebp*, where "metadata" is set to "exif"
```php
$options = [
'metadata' => 'all',
'cwebp-metadata' => 'exif'
];
```
Prefixing is by the way a general feature in the way options are handled and thus not confined to the stack converter. (though it admittedly only finds its use in the context of a stack converter).
#### 2. Using the `converter-options` option
The *converter-options* option is convenient for setting a whole bunch of converter-specific options in one go.
Example:
```php
$options = [
'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,
],
],
]
```
#### 3. As part of the `converters` option
This option is explained further down this document.
## Modifying the stack
The default stack consists of the following converters:
- cwebp
- vips
- imagick
- gmagick
- imagemagick
- graphicsmagick
- wpc
- ewww
- gd
The order has carefully been chosen based on the capabilities of the converters. It is a rank, if you will.
Now, say that on your system, you only have *gd* working. With the default stack, this means that eight converters will be tested for operationality before getting to *gd* – each time a conversion is made. You might be tempted to optimizing the flow by putting *gd* on the top. *I would generally advise against this* for the following reasons:
1. It might be that one of the other (and better) converters starts working without you noticing. You will then miss out.
2. All converters have all been designed to exit very quickly when they are not operational. It only takes a few milliseconds for the library to detect that a converter is not operational - literally. For example, if no api key is provided for ewww, it will exit immediately.
However, there are valid reasons to modify the stack. For example, you may prefer *vips* over *cwebp*, or you may wish to remove a converter completely due to problems with that converter on your platform.
### Changing the order of the converters
To change the order, you can use the `preferred-converters` option. With this option you move selected converters to the top of the stack.
So, if you want the stack to start with *vips* and then *ewww*, but keep the rest of the order, you can set the following:
```php
$options[
'preferred-converters' => ['vips', 'ewww'];
];
```
### Removing converters from the stack
To remove converters, you can use the `skip` option and prefixing. For example, to remove *cwebp* and *gd*:
```php
$options = [
'ewww-skip' => true,
'cwebp-skip' => true,
];
```
### Adding converters to the stack
If you are using a custom converter, you can add it to the stack like this:
```php
$options = [
'extra-converters' => [
'\\MyNameSpace\\WonderConverter'
],
];
```
It will be added to the bottom of the stack. To place it differently, use the `preferred-converters` option and set it to ie `'preferred-converters' => ['vips','\\MyNameSpace\\WonderConverter']`
Here is an example which adds an extra ewww converter. This way you can have a backup api-key in case the quota of the first has been exceeded.
```
$options = [
'extra-converters' => [
[
'converter' => 'ewww',
'options' => [
'api-key' => 'provide-backup-key-here',
]
]
]
];
```
Note however that you will not be able to reorder that new ewww converter using `preferred-converters`, as there are now two converters with id=ewww, and that option has not been designed for that. Instead, you can add a sub-stack of ewww converters - see the "Stacking" section below.
### Setting the converter array explicitly
Using the `converters` option, you can set the converter array explicitly. What differentiates this from the `preferred-converters` option (besides that it completely redefines the converter ordering) is that it allows you to set both the converters *and* options for each converter in one go and that it allows a complex structure - such as a stack within a stack. Also, this structure can simplify things in some cases, such as when the options is generated by a GUI, as it is in WebP Express.
The array specifies the converters to try and their order. Each item can be:
- An id (ie "cwebp")
- A fully qualified class name (in case you have programmed your own custom converter)
- An array with two keys: "converter" and "options".
Example:
```php
$options = [
'quality' => 71,
'converters' => [
'cwebp',
[
'converter' => 'vips',
'options' => [
'quality' => 72
]
],
[
'converter' => 'ewww',
'options' => [
'quality' => 73
]
],
'wpc',
'imagemagick',
'\\MyNameSpace\\WonderConverter'
],
];
```
### Stacking
Stack converters behave just like regular converters. They ARE in fact "regular", as they extend the same base class as all converters. This means that you can have a stack within a stack. You can for example utilize this for supplying a backup api key for the ewww converter. Like this:
```php
$options = [
'ewww-skip' => true, // skip the default ewww converter (we use stack of ewww converters instead)
'extra-converters' => [
[
// stack of ewww converters
'converter' => 'stack',
'options' => [
'ewww-skip' => false, // do not skip ewww from here on
'converters' => [
[
'converter' => 'ewww',
'options' => [
'api-key' => 'provide-preferred-key-here',
]
],
[
'converter' => 'ewww',
'options' => [
'api-key' => 'provide-backup-key-here',
]
]
],
]
]
],
'preferred-converters' => ['cwebp', 'vips', 'stack'], // set our stack of ewww converters third in queue
];
```
Note that we set `ewww-skip` in order to disable the *ewww* converter which is part of the defaults. As options are inherited, we have to reset this option again. These steps are not necessary when using the `converters` option.
Also note that the options for modifying the converters (`converters`, `extra-converters`, `converter-options`) does not get passed down.
Also note that if you want to add two stacks with `extra-converters`, the `preferred-converters` option will not work, as there are two converters called "stack". One workaround is to add those two stacks to their own stack, so you have three levels. Or you can of course simply use the `converters` option to get complete control.
### Shuffling
The stack can be configured to shuffling, meaning that the the order will be random. This can for example be used to balance load between several wpc instances in a sub stack.
Shuffling is enabled with the `shuffle` option.
Here is an example of balancing load between several *wpc* instances:
```php
$options = [
'wpc-skip' => true, // skip the default wpc converter (we use stack of wpc converters instead)
'extra-converters' => [
[
// stack of wpc converters
'converter' => 'stack',
'options' => [
'wpc-skip' => false, // do not skip wpc from here on
'shuffle' => true,
'converters' => [
[
'converter' => 'wpc',
'options' => [
'api-key' => 'my-dog',
'api-url' => 'my-wpc.com/wpc.php',
'api-version' => 1,
'crypt-api-key-in-transfer' => true,
]
],
[
'converter' => 'wpc',
'options' => [
'api-key' => 'my-other-dog',
'api-url' => 'my-other-wpc.com/wpc.php',
'api-version' => 1,
'crypt-api-key-in-transfer' => true,
]
]
],
]
]
],
'preferred-converters' => ['cwebp', 'vips', 'stack'], // set our stack of wpc converters third in queue
];
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

View File

@@ -0,0 +1,251 @@
# 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:
```php
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:
```php
use WebPConvert\Convert\Converters\Gd;
use WebPConvert\Loggers\EchoLogger;
Gd::convert($source, $destination, $options=[], new EchoLogger());
```
It will output something like this:
```text
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:
```php
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:
```php
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](https://raw.githubusercontent.com/rosell-dk/webp-convert/master/docs/v2.0/converting/architecture-q50-w600.jpg)
### 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](https://raw.githubusercontent.com/rosell-dk/webp-convert/master/docs/v2.0/converting/dice.png)
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](https://groups.google.com/a/webmproject.org/forum/#!topic/webp-discuss/0GmxDmlexek)
### 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](https://developers.google.com/speed/webp/docs/cwebp) and [here](https://www.smashingmagazine.com/2018/07/converting-images-to-webp/)
### 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](https://www.ctrl.blog/entry/webp-sharp-yuv.html).
### 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](https://raw.githubusercontent.com/rosell-dk/webp-convert/master/docs/v2.0/converting/mouse-q100.jpg)
### 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):
```php
$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):
```php
$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:
```php
$options = [
'png' => [
'converters' => ['ewww'],
],
'jpeg' => [
'converters' => ['gd'],
]
];
```
## Available options
**All** available options are documented [here](https://github.com/rosell-dk/webp-convert/blob/master/docs/v2.0/converting/options.md).
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".<br><br>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".<br><br>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](https://www.bitwise-it.dk/webp-convert/api/2.0/html/index.xhtml)
- The converters are described in more detail here (for 1.3.9): [docs/v1.3/converting/converters.md](https://github.com/rosell-dk/webp-convert/blob/master/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](https://github.com/rosell-dk/webp-convert/blob/master/docs/v1.3/converting/convert.md).

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

View File

@@ -0,0 +1,403 @@
# Options
This is a list of all options available for converting.
Note that as the *stack* and *wpc* converters delegates the options to their containing converters, the options that they supports depend upon the converters they have been configured to use (and which of them that are operational)<br><br>
## General options
### `alpha-quality`
```
Type: integer (0-100)
Default: 85
Supported by: cwebp, vips, imagick, gmagick, imagemagick and graphicsmagick
```
Quality of alpha channel. Often, there is no need for high quality transparency layer and in some cases you can tweak this all the way down to 10 and save a lot in file size. The option only has effect with lossy encoding, and of course only on images with transparency (so it is irrelevant when converting jpegs). Read more about tweaking the option [here](https://github.com/rosell-dk/webp-convert/blob/master/docs/v2.0/converting/introduction-for-converting.md#alpha-quality)<br><br>
### `auto-filter`
```
Type: boolean
Default: false
Supported by: cwebp, vips, imagick, gmagick, imagemagick and graphicsmagick
```
Turns auto-filter on. This algorithm will spend additional time optimizing the filtering strength to reach a well-balanced quality. Unfortunately, it is extremely expensive in terms of computation. It takes about 5-10 times longer to do a conversion. A 1MB picture which perhaps typically takes about 2 seconds to convert, will takes about 15 seconds to convert with auto-filter. So in most cases, you will want to leave this at its default, which is off.<br><br>
### `auto-limit`
```
Type: boolean
Default: true
Supported by: all
```
Limits the quality to be no more than that of the jpeg. The option is only relevant when converting jpegs to lossy webp. To be functional, webp-convert needs to be able to detect the quality of the jpeg, which requires ImageMagick or GraphicsMagick. Read about the option in the [introduction](https://github.com/rosell-dk/webp-convert/blob/master/docs/v2.0/converting/introduction-for-converting.md#auto-quality). In 2.7.0, it will become possible to adjust the limit with a new option. I'm currently debating with myself how this should work. Your comments and opinions would be appreciated - [here](https://github.com/rosell-dk/webp-convert/issues/289)
### `converter` (new in 2.8.0)
```
Type: string
Default: null
Supported by: WebPConvert::convert method
```
Simplifies using a specific converter. Before this option, you would either need to call the converter class (ie `Ewww::convert`) (not very flexible), or set the stack to contain just one converter (unnecessary overhead). If you do not use this option, `WebPConvert::convert` works as normal (it calls `Stack::convert`), if you do use it, it hands over the converting to the converter specified (specified by id, ie. "cwebp").
### `default-quality` (DEPRECATED)
```
Type: integer (0-100)
Default: 75 for jpegs and 85 for pngs
Supported by: all (cwebp, ewww, gd, ffmpeg, gmagick, graphicsmagick, imagick, imagemagick, vips)
```
This option has been deprecated. See why [here](https://github.com/rosell-dk/webp-convert/issues/281). It was used to determine the quality in case auto limiting was not available.<br><br>
### `encoding`
```
Type: string ("lossy" | "lossless" | "auto")
Default: "auto"
Supported by: cwebp, vips, ffmpeg, imagick, gmagick, imagemagick and graphicsmagick (gd always uses lossy encoding, ewww uses lossless for pngs and lossy for jpegs)
```
Set encoding for the webp. If you choose "auto", webp-convert will convert to both lossy and lossless and pick the smallest result. Read more about this option in the ["lossy/lossless" section in the introduction](https://github.com/rosell-dk/webp-convert/blob/master/docs/v2.0/converting/introduction-for-converting.md#auto-selecting-between-losslesslossy-encoding).<br><br>
### `ewww-api-key`
```
Type: string
Default: ''
Supported by: ewww
```
Api key for the ewww converter. The option is actually called *api-key*, however, any option can be prefixed with a converter id to only apply to that converter. As this option is only for the ewww converter, it is natural to use the "ewww-" prefix.
Note: This option can alternatively be set through the *EWWW_API_KEY* environment variable.<br><br>
### `ewww-check-key-status-before-converting`
```
Type: boolean
Default: true
Supported by: ewww
```
Decides whether or not the ewww service should be invoked in order to check if the api key is valid. Doing this for every conversion is not optimal. However, it would be worse if the service was contacted repeatedly to do conversions with an invalid api key - as conversion requests carries a big upload with them. As this library cannot prevent such repeated failures (it is stateless), it per default does the additional check. However, your application can prevent it from happening by picking up invalid / exceeded api keys discovered during conversion. Such failures are stored in `Ewww::$nonFunctionalApiKeysDiscoveredDuringConversion` (this is also set even though a converter later in the stack succeeds. Do not only read this value off in a catch clauses).
You should only set this option to *false* if you handle when the converter discovers invalid api keys during conversion.
### `jpeg`
```
Type: array
Default: []
Supported by: all
```
Override selected options when the source is a jpeg. The options provided here are simply merged into the other options when the source is a jpeg.
Read about this option in the [introduction](https://github.com/rosell-dk/webp-convert/blob/master/docs/v2.0/converting/introduction-for-converting.md#png-og-jpeg-specific-options).<br><br>
### `log-call-arguments`
```
Type: boolean
Default: false
Supported by: all
```
Enabling this simply puts some more in the log - namely the arguments that was supplied to the call. Sensitive information is starred out.
### `low-memory`
```
Type: boolean
Default: false
Supported by: cwebp, imagick, imagemagick and graphicsmagick
```
Reduce memory usage of lossy encoding at the cost of ~30% longer encoding time and marginally larger output size. Only effective when the *method* option is 3 or more. Read more in [the docs](https://developers.google.com/speed/webp/docs/cwebp).<br><br>
### `max-quality` (DEPRECATED)
```
Type: integer (0-100)
Default: 85
Supported by: all (cwebp, ewww, ffmpeg, gd, gmagick, graphicsmagick, imagick, imagemagick, vips)
```
This option has been deprecated. See why [here](https://github.com/rosell-dk/webp-convert/issues/281)<br><br>
### `metadata`
```
Type: string ("all" | "none" | "exif" | "icc" | "xmp" | "exif,icc" | "exif,xmp" | "icc,xmp")
Default: 'none'
Supported by: Only *cwebp* supports "exif", "icc" and "xmp". *gd* cannot copy metadata. *ffmpeg* always copies metadata. The rest supports "all" and "none" (ewww, gmagick, graphicsmagick, imagick, imagemagick, vips)
```
Determines which metadata that should be copied over to the webp. Setting it to "all" preserves all metadata, setting it to "none" strips all metadata. *cwebp* can take a comma-separated list of which kinds of metadata that should be copied (ie "exif,icc"). *gd* will always remove all metadata and *ffmpeg* will always keep all metadata. The rest can either strip all or keep all (they will keep all, unless the option is set to *none*).<br><br>
### `method`
```
Type: integer (0-6)
Default: 6
Supported by: cwebp, vips, imagick, gmagick, imagemagick, graphicsmagick and ffmpeg
```
This parameter controls the trade off between encoding speed and the compressed file size and quality. Possible values range from 0 to 6. 0 is fastest. 6 results in best quality. PS: "method" is not a very descriptive name, but this is what its called in libwebp, which is why we also choose it for webpconvert. In ffmpeg, they renamed it "compression_level", in vips, they call it "reduction_effort". Both better names, but as said, use "method" with webpconvert<br><br>
### `near-lossless`
```
Type: integer (0-100)
Default: 60
Supported by: cwebp, vips
```
This option allows you to get impressively better compression for lossless encoding, with minimal impact on visual quality. The result is still lossless (lossless encoding). What libwebp does is that it preprocesses the image before encoding it, in order to make it better suited for compression. The range is 0 (maximum preprocessing) to 100 (no preprocessing). A good compromise would be around 60. The option is ignored when encoding is set to lossy. Read more [here](https://github.com/rosell-dk/webp-convert/blob/master/docs/v2.0/converting/introduction-for-converting.md#near-lossless).<br><br>
### `png`
```
Type: array
Default: []
Supported by: all
```
Override selected options when the source is a png. The options provided here are simply merged into the other options when the source is a png.
Read about this option in the [introduction](https://github.com/rosell-dk/webp-convert/blob/master/docs/v2.0/converting/introduction-for-converting.md#png-og-jpeg-specific-options).<br><br>
### `preset`
```
Type: string ('none', 'default', 'photo', 'picture', 'drawing', 'icon' or 'text')
Default: "none"
Supported by: cwebp, vips, gmagick, graphicsmagick, imagick, imagemagick, ffmpeg
```
Using a preset will set many of the other options to suit a particular type of source material. It even overrides them. It does however not override the quality option. "none" means that no preset will be set. PS: The imagemagick family only partly supports this setting, as they have grouped three of the options ("drawing", "icon" and "text") into "graph". So if you for example set "preset" to "icon" with the imagemagick converter, imagemagick will be executed like this: "-define webp:image-hint='graph'".<br><br>
### `quality`
```
Type: integer (0-100) | "auto" ("auto" is now deprecated - use the "auto-limit" option instead)
Default: 75 for jpegs and 85 for pngs
Supported by: all (cwebp, ewww, gd, gmagick, graphicsmagick, imagick, imagemagick, vips, ffmpeg)
```
Quality for lossy encoding.<br><br>
### `sharp-yuv`
```
Type: boolean
Default: true
Supported by: cwebp, vips, gmagick, graphicsmagick, imagick, imagemagick
```
Better RGB->YUV color conversion (sharper and more accurate) at the expense of a little extra conversion time. Read more [here](https://www.ctrl.blog/entry/webp-sharp-yuv.html).
### `size-in-percentage`
```
Type: integer (0-100) | null
Default: null
Supported by: cwebp
```
This option sets the file size, *cwebp* should aim for, in percentage of the original. If you for example set it to *45*, and the source file is 100 kb, *cwebp* will try to create a file with size 45 kb (we use the `-size` option). This is an excellent alternative to the "quality:auto" option. If the quality detection isn't working on your system (and you do not have the rights to install imagick or gmagick), you should consider using this options instead. *Cwebp* is generally able to create webp files with the same quality at about 45% the size. So *45* would be a good choice. The option overrides the quality option. And note that it slows down the conversion - it takes about 2.5 times longer to do a conversion this way, than when quality is specified. Default is *off* (null).<br><br>
### `skip`
```
Type: boolean
Default: false
Supported by: all
```
Simply skips conversion. For example this can be used to skip png conversion for a specific converter like this:
```php
$options = [
'png' => [
'gd-skip' => true,
]
];
```
Or it can be used to skip unwanted converters from the default stack, like this:
```php
$options = [
'ewww-skip' => true,
'wpc-skip' => true,
'gd-skip' => true,
'imagick-skip' => true,
'gmagick-skip' => true,
];
```
<br>
### `use-nice`
```
Type: boolean
Default: false
Supported by: cwebp, graphicsmagick, imagemagick, ffmpeg
```
This option only applies to converters which are using exec() to execute a binary directly on the host. If *use-nice* is set, it will be examined if the [`nice`]( https://en.wikipedia.org/wiki/Nice_(Unix)) command is available on the host. If it is, the binary is executed using *nice*. This assigns low priority to the process and will save system resources - but result in slower conversion.<br><br>
# Options unique for individual converters
## cwebp options
Options unique to the "cwebp" converter
### `command-line-options`
```
Type: string
Default: ''
Supported by: cwebp
```
This allows you to set any parameter available for cwebp in the same way as you would do when executing *cwebp*. You could ie set it to "-sharpness 5 -mt -crop 10 10 40 40". Read more about all the available parameters in [the docs](https://developers.google.com/speed/webp/docs/cwebp).<br><br>
### `rel-path-to-precompiled-binaries`
```
Type: string
Default: './Binaries'
Supported by: cwebp
```
Allows you to change where to look for the precompiled binaries. While this may look as a risk, it is completely safe, as the binaries are hash-checked before being executed. The option is needed when you are using two-file version of webp-on-demand.
### `try-cwebp`
```
Type: boolean
Default: true
Supported by: cwebp
```
If set, the converter will try executing "cwebp -version". In case it succeeds, and the version is higher than those working cwebp's found using other methods, the conversion will be done by executing this cwebp.
### `try-common-system-paths`
```
Type: boolean
Default: true
Supported by: cwebp
```
If set, the converter will look for a cwebp binaries residing in common system locations such as `/usr/bin/cwebp`. If such exist, it is assumed that they are valid cwebp binaries. A version check will be run on the binaries found (they are executed with the "-version" flag. The cwebp with the highest version found using this method and the other enabled methods will be used for the actual conversion.
This method might find a cwebp binary something that isn't found using `try-discovering-cwebp` if these common paths are not within PATH or neither `which` or `whereis` are available.
Note: All methods for discovering cwebp binaries are per default enabled. You can save a few microseconds by disabling all, but the one that discovers the cwebp binary with the highest version (check the conversion log to find out). However, it is probably not worth it, as your setup will then become less resilient to system changes.
### `try-discovering-cwebp`
```
Type: boolean
Default: true
Supported by: cwebp
```
If set, the converter will try to discover installed cwebp binaries using the `which -a cwebp` command, or in case that fails, the `whereis -b cwebp` command. These commands will find cwebp binaries residing in PATH
### `try-supplied-binary-for-os`
```
Type: boolean
Default: true
Supported by: cwebp
```
If set, the converter will try use a precompiled cwebp binary that comes with webp-convert. But only if it has a higher version that those found by other methods. As the library knows the versions of its cwebps, no additional time is spent executing them with the "-version" parameter. The binaries are hash-checked before executed. The library btw. comes with several versions of precompiled cwebps because they have different dependencies - some works on some systems and others on others.
### `skip-these-precompiled-binaries`
```
Type: string
Default: ''
Supported by: cwebp
```
The precompiled binaries from google have dependencies, and they are different. This means that some of them works on some systems, others on others. For this reason, several precompiled binaries are shipped with the library - we want it to simply work on as many systems as possible. Of course, the binary with the highest version number is tried first. But if it doesn't work, time has been wasted running an executable that doesn't work, and validating the hash before running it. To avoid this, use this option to bypass precompiled binaries that you know doesn't work on your current system. You pass in the filenames (comma separated), ie "cwebp-120-linux-x86-64,cwebp-110-linux-x86-64". In order to see if time is wasted on a supplied binary, that doesn't work, check the conversion log. You can also get info about the filenames of the binaries in the conversion log. Instructions on viewing the conversion log are available [here](https://github.com/rosell-dk/webp-convert/blob/master/docs/v2.0/converting/introduction-for-converting.md#insights-to-the-process).
Btw: If minimizing the overhead is a priority, there are alternatives to this option that speeds up conversion time more. It is the hash-check that is costly. Hash-checking is only done on the cwebps shipped with the library.
Alternative 1: Disabling the "cwebp-try-supplied-binary-for-os" option thus avoids the rather expensive job of hash-checking the binary each time it is run. The cost of this is that you don't get the newest cwebp available (the ones shipped with the library will only be used when you don't have a newer one available).
Alternative 2: If you set an environment variable called "WEBPCONVERT_CWEBP_PATH" (or define a "WEBPCONVERT_CWEBP_PATH" variable in PHP), cwebp will simply execute the binary found at that path and not examine other alternatives. Also, there will be no hash check either. Doing so however makes your system a little bit less secure - exactly because it bypasses the hash-checking. If some security whole allows an attacker to upload a binary, replacing the one set like this, an attacker would then have a way to have that binary executed. Here is how you define the variable in PHP: `define("WEBPCONVERT_CWEBP_PATH", "/path/to/working/cwebp/for/example/one/in/src/Convert/Converters/Binaries/dir");`. Also beware that by doing this, you will need to update your code in order to take advantage of future cwebp releases.
## stack options
Options unique to the "stack" converter
### `stack-converters`
```
Type: array
Default: ['cwebp', 'vips', 'imagick', 'gmagick', 'imagemagick', 'graphicsmagick', 'wpc', 'ewww', 'gd']
Supported by: stack
```
Specify the converters to try and their order.
Beware that if you use this option, you will miss out when more converters are added in future updates. If the purpose of setting this option is to remove converters that you do not want to use, you can use the *skip* option instead. Ie, to skip ewww, set *ewww-skip* to true. On the other hand, if what you actually want is to change the order, you can use the *stack-preferred-converters* option, ie setting *stack-preferred-converters* to `['vips', 'wpc']` will move vips and wpc in front of the others. Should they start to fail, you will still have the others as backup.
The array specifies the converters to try and their order. Each item can be:
- An id (ie "cwebp")
- A fully qualified class name (in case you have programmed your own custom converter)
- An array with two keys: "converter" and "options".
`
Alternatively, converter options can be set using the *converter-options* option.
Read more about the stack converter in the [introduction](https://github.com/rosell-dk/webp-convert/blob/master/docs/v2.0/converting/introduction-for-converting.md#the-stack-converter).<br><br>
### `stack-converter-options`
```
Type: array
Default: []
Supported by: stack
```
Extra options for specific converters. Example:
```php
$options = [
'converter-options' => [
'vips' => [
'quality' => 72
],
]
]
```
<br>
### `stack-extra-converters`
```
Type: array
Default: []
Supported by: stack
```
Add extra converters to the bottom of the stack. The items are similar to those in the `stack-converters` option.<br><br>
### `stack-preferred-converters`
```
Type: array
Default: []
Supported by: stack
```
With this option you can move specified converters to the top of the stack. The converters are specified by id. For example, setting this option to ['vips', 'wpc'] ensures that *vips* will be tried first and - in case that fails - *wpc* will be tried. The rest of the converters keeps their relative order.<br><br>
### `stack-shuffle`
```
Type: boolean
Default: false
Supported by: stack
```
Shuffle the converters in the stack. This can for example be used to balance load between several wpc instances in a substack, as illustrated [here](https://github.com/rosell-dk/webp-convert/blob/master/docs/v2.0/converting/converters/stack.md)<br><br>
## vips options
### `vips-smart-subsample` (DEPRECATED)
```
Type: boolean
Default: false
Supported by: vips
```
This feature seemed not to be part of *libwebp* but intrinsic to vips. However, we were wrong - the feature is the same as 'sharp-yuv'. Use that instead.<br><br>
## wcp options
### `wpc-api-key`
```
Type: string
Default: ''
Supported by: wpc
```
Api key for the wpc converter. The option is actually called *api-key*, however, any option can be prefixed with a converter id to only apply to that converter. As this option is only for the wpc converter, it is natural to use the "wpc-" prefix. Same goes for the other "wpc-" options.
Note: You can alternatively set the api key through the *WPC_API_KEY* environment variable.<br><br>
### `wpc-api-url`
```
Type: string
Default: ''
Supported by: wpc
```
Note: You can alternatively set the api url through the *WPC_API_URL* environment variable.<br><br>
### `wpc-api-version`
```
Type: integer (0 - 1 - 2)
Default: 2
Supported by: wpc
```
PS: In many releases, you had to set this to 1 even though you were running on 2. This will be fixed in 2.9.0
<br>
### `wpc-crypt-api-key-in-transfer`
```
Type: boolean
Default: false
Supported by: wpc
```
<br>
### `wpc-secret`
```
Type: string
Default: ''
Supported by: wpc
```
Note: This option is only relevant for api version 0.