@@ -19,6 +19,8 @@ by generating multiple derivative images from one or more sources.
1919
2020* Image Process* will not overwrite your original images.
2121
22+ ![ Image Process overview] ( image-process-overview.svg )
23+
2224## Installation
2325
2426The easiest way to install * Image Process* is via Pip. This
@@ -64,7 +66,7 @@ compute a thumbnail from a larger image:
6466
6567``` python
6668IMAGE_PROCESS = {
67- " article-image" : [" scale_in 300 300 True" ],
69+ " article-image" : ( [" scale_in 300 300 True" ], " webp " )
6870 " thumb" : [" crop 0 0 50% 50% " , " scale_out 150 150 True" , " crop 0 0 150 150" ],
6971}
7072```
@@ -74,13 +76,22 @@ referred to by the `src` attribute of an `<img>` according to the
7476list of operations specified, and replace the ` src ` attribute with the
7577URL of the transformed image.
7678
79+ You can also transcode the image from one image format into another, for
80+ example, from ` png ` to ` webp ` . Supported are all image formats that are also
81+ supported by the underlying Pillow library (see [ Image File
82+ Formats] ( #image-file-formats ) ). This is useful when you want to keep a single
83+ large high-resolution image in your repository, but distribute a more
84+ lightweight, web-optimized image with your web site.
85+
7786For consistency with other types of transformations described
7887below, there is an alternative syntax for the processing instructions:
7988
89+
8090``` python
8191IMAGE_PROCESS = {
8292 " thumb" : {
8393 " type" : " image" ,
94+ " output-format" : " webp"
8495 " ops" : [" crop 0 0 50% 50% " , " scale_out 150 150 True" , " crop 0 0 150 150" ],
8596 },
8697 " article-image" : {
@@ -149,25 +160,27 @@ dictionary, with the following syntax:
149160IMAGE_PROCESS = {
150161 " crisp" : {
151162 " type" : " responsive-image" ,
163+ " output-format" : " webp" ,
152164 " srcset" : [
153- (" 1x" , [" scale_in 800 600 True" ]),
165+ (" 1x" , [" scale_in 800 600 True" ], " avif " ),
154166 (" 2x" , [" scale_in 1600 1200 True" ]),
155- (" 4x" , [" scale_in 3200 2400 True" ]),
167+ (" 4x" , [" scale_in 3200 2400 True" ], " original " ),
156168 ],
157169 " default" : " 1x" ,
158170 },
159171 " large-photo" : {
160172 " type" : " responsive-image" ,
173+ " output-format" : " jpg" ,
161174 " sizes" : (
162175 " (min-width: 1200px) 800px, "
163176 " (min-width: 992px) 650px, "
164177 " (min-width: 768px) 718px, "
165178 " 100vw"
166179 ),
167180 " srcset" : [
168- (" 600w" , [" scale_in 600 450 True" ]),
181+ (" 600w" , [" scale_in 600 450 True" ], " webp " ),
169182 (" 800w" , [" scale_in 800 600 True" ]),
170- (" 1600w" , [" scale_in 1600 1200 True" ]),
183+ (" 1600w" , [" scale_in 1600 1200 True" ], " original " ),
171184 ],
172185 " default" : " 800w" ,
173186 },
@@ -199,6 +212,25 @@ width in pixels of the associated image and must have the suffix
199212attribute of the image. This is the image that will be displayed by
200213browsers that do not support the ` srcset ` syntax.
201214
215+ Both definitions above also demonstrate how
216+ the input image may be transcoded into another file format. This allows you to
217+ transcode your image from, for example, a ` png ` original to ` webp `
218+ derivative images. The setting ` "output-format": "jpg" ` sets the default for the
219+ derivative images. This default can be overriden in each ` srcset `
220+ specification. In the ` large-photo ` example above, by default, all derivative
221+ images will be transcoded into ` jpg ` , however the line `("600w", [ "scale_in 600
222+ 450 True"] , "webp"),` will override this for this specific derivative image. You
223+ can also specify that you want to keep the original format, by using the keyword
224+ ` original ` instead of an image file format specification.
225+
226+ Similarly, the ` crisp ` transformation also specifies a top-level output format
227+ ` "output-format": "webp" ` , which means that in absence of other specifications,
228+ the derivative images will be transcoded into the * WebP* image format. However,
229+ within the ` srcset ` this is overruled: the ` 1x ` derivative image will be
230+ transcoded into ` avif ` , the ` 2x ` image will be transcoded into ` webp ` (as
231+ specified by ` output-format ` ), and lastly the ` 4x ` image will retain the original
232+ image format.
233+
202234In the two examples above, the ` default ` setting is a string referring to
203235one of the images in the ` srcset ` . However, the ` default ` value
204236could also be a list of operations to generate a different derivative
@@ -253,6 +285,7 @@ IMAGE_PROCESS = {
253285 " sources" : [
254286 {
255287 " name" : " default" ,
288+ " output-format" : " webp" ,
256289 " media" : " (min-width: 640px)" ,
257290 " srcset" : [
258291 (" 640w" , [" scale_in 640 480 True" ]),
@@ -264,7 +297,7 @@ IMAGE_PROCESS = {
264297 {
265298 " name" : " source-1" ,
266299 " srcset" : [
267- (" 1x" , [" crop 100 100 200 200" ]),
300+ (" 1x" , [" crop 100 100 200 200" ], " avif " ),
268301 (" 2x" , [" crop 100 100 300 300" ]),
269302 ]
270303 },
@@ -285,6 +318,10 @@ displayed by browsers that do not support the `<picture>` syntax. In
285318this example, it will use the image ` 640w ` from the source ` default ` .
286319A list of operations could have been specified instead of ` 640w ` .
287320
321+ Similar to ` responsive image ` described above, ` <picture> ` also allows the
322+ specification of "output-format" and image format extensions like ` webp ` ,
323+ ` avif ` , and ` jpg ` .
324+
288325To generate a responsive ` <picture> ` for the images in your
289326articles, you must add to your article a pseudo ` <picture> ` tag that
290327looks like this:
@@ -430,6 +467,67 @@ IMAGE_PROCESS = {
430467}
431468```
432469
470+ ### Image File Formats
471+
472+ * Image Process* uses Python's Pillow library (PIL) to read and write files. The
473+ file formats that Pillow can read and write depend on libraries/plugins that
474+ may or may not be installed on a particular system. While most common image
475+ formats will likely work out of the box (` png ` , ` jpg ` , ` jpeg ` , ` gif ` , ` tif ` ,
476+ ` webp ` ), uncommon formats may cause issues depending on the system you are
477+ working on.
478+
479+ To specify an image format for the derivative image, Pillow will infer the image
480+ format from the file extension you specify. This follows common conventions, for
481+ example: the extensions ` j2c ` , ` j2k ` , ` jp2 ` , and ` jpx ` will all result in a
482+ * JPEG2000* file, while ` jpe ` , ` jpg ` , and ` jpeg ` will produce a * JPEG* derivative
483+ file.
484+
485+ To see a full list of extensions and file formats available on your system, run
486+ the following Python snippet:
487+
488+ ``` python
489+ from PIL import Image
490+
491+ # Map every available image extension to its format
492+ Image.init()
493+ print (f " { ' Extension' .ljust(10 )} -> { ' Format' .ljust(10 )} | Read/Write " )
494+ for ext, fmt in sorted (Image.EXTENSION .items()):
495+ readonly = (" " if Image.SAVE .get(fmt) else " | READ-ONLY" )
496+ writeonly = (" " if Image.OPEN .get(fmt) else " | WRITE-ONLY" )
497+ print (f " { ext.ljust(10 )} -> { fmt.ljust(10 )} { readonly}{ writeonly} " )
498+ ```
499+
500+ Not all image formats can be read * and* written. For example, the * PDF* image
501+ format can be written with Pillow, but cannot be read. Consequently, it can be
502+ used as ` output-format ` by * Image Process* but does not work when you attempt to
503+ use it as the original input format.
504+
505+ The ability to * display* a particular image format depends on the browser.
506+ Modern browsers will typically support the following formats: JPEG, PNG, GIF,
507+ SVG, WebP, AVIF (and ICO).
508+
509+ For displaying images on your Pelican web site consider the following output formats:
510+
511+ | Format | Best For... | Browser Support |
512+ | ---| ---| ---|
513+ | JPEG | Standard photo (no transparency) | 100% |
514+ | PNG | Graphics including transparency | 100% |
515+ | WebP | All-purpose images (smaller size than JPEG/PNG) | ~ 97% (modern) |
516+ | AVIF | All-purpose images (smaller size than WebP) | ~ 94% (latest) |
517+ | GIF | Simple, low-resolution animations. | 100% |
518+
519+ For most use cases, selecting either * AVIF* or * WebP* as output format (setting
520+ ` output-format ` ), with a fallback (setting ` default ` ) of * JPEG* or * PNG* will
521+ give good results.
522+
523+ The * SVG* image format is omitted on purpose from the list above; it is a
524+ * vector* image format (as opposed to the others, which are * raster* formats),
525+ that is best used for logos and illustrations. You should not blindly convert
526+ images (especially not photographs!) to this format unless you are sure what you
527+ are doing. For more information on how vector image formats compare to raster
528+ image formats, see this [ Wikipedia
529+ article] ( https://en.wikipedia.org/wiki/Vector_graphics ) .
530+
433531### Additional Settings
434532
435533#### Destination Directory
@@ -638,9 +736,12 @@ is a helper function to do this for you. From the Python REPL:
638736``` python
639737>> > from pelican.plugins.image_process.test_image_process import generate_test_images
640738>> > generate_test_images()
641- 36 test images generated!
739+ 60 test images generated!
642740```
643741
742+ This generates both standard transform test images (54) and format conversion
743+ test images (6 for WebP and AVIF).
744+
644745## License
645746
646747This project is licensed under the [ AGPL-3.0 license] ( http://www.gnu.org/licenses/agpl-3.0.html ) .
0 commit comments