Transcode image format#102
Transcode image format#102cargocultprogramming wants to merge 11 commits intopelican-plugins:mainfrom
Conversation
|
Thank you @cargocultprogramming ! I will take a bit more time to review the code, but here are some thoughts from my first pass review; please comment if any of these things are proving to be frustrating to resolve on your side.
|
patrickfournier
left a comment
There was a problem hiding this comment.
Thanks for your work, this is very much appreciated.
Code
Overall, the implementation looks good. I left a few comments, mostly related to falling back to a default setting for the picture transform type. Maybe it was not clear from my comment in the related issue, but I was thinking the default output-format could be used with all transform types. So for pictures, we would have:
IMAGE_PROCESS = {
"example-pict": {
"type": "picture",
"output-format": "webp", # Default format
"sources": [
{
"name": "default",
"media": "(min-width: 640px)",
"srcset": [
("640w", ["scale_in 640 480 True"]),
("1024w", ["scale_in 1024 683 True"]),
("1600w", ["scale_in 1600 1200 True"]),
],
"sizes": "100vw",
},
{
"name": "source-1",
"srcset": [
("1x", ["crop 100 100 200 200"]),
("2x", ["crop 100 100 300 300"]),
]
},
],
"default": ("default", "640w"),
},
}
Tests
Please test all possible syntaxes:
- Image replacement: please add a test for the short syntax (
"article-image": (["scale_in 300 300 True"], 'webp') . - Responsive image: please add a test to check proper behavior when
output-formatis not specified. - Picture set: please add a test that uses the default
output-format - For responsive images and/or picture, it would be nice to have a test for the case where
defaultspecifies a transform instead of a name, for example:"default": (["scale_in 1600 1200 True"], "webp")instead of"default": "800w"
Documentation
As @minchinweb mentioned, please update the README to document the feature and the new syntax.
| elif isinstance(default[1], list): | ||
| elif isinstance(default[1], (list, tuple)): | ||
| default_item_name = "default" | ||
| default_item_format = get_target_format(default[1]) |
There was a problem hiding this comment.
Same here: shouldn't we fallback to IMAGE_PROCESS[derivative]['output-format'] ?
There was a problem hiding this comment.
I do not think this comment is addressed. See https://github.com/pelican-plugins/image-process/pull/102/changes#r3083171388
| elif isinstance(default[1], list): | ||
| elif isinstance(default[1], (list, tuple)): | ||
| default_item_name = "default" | ||
| default_item_format = get_target_format(default[1]) |
There was a problem hiding this comment.
Same here: shouldn't we fallback to IMAGE_PROCESS[derivative]['output-format'] if get_target_format() returns None?
There was a problem hiding this comment.
I do not think this comment is addressed. If we have:
"picture_formats": {
"type": "picture",
"sources": [
{
"name": "webp-src",
"output-format": "webp",
"srcset": [
("640w", ["scale_in 640 480 True"]),
("1024w", ["scale_in 1024 768 True"]),
],
},
],
"default": ("webp-src", ["scale_in 500 500 True"]),
},
default_item_format will not fallback to webp from output-format.
|
I've added a number of commits today (1e959d5 to e22ee04), to address the comments of @minchinweb :
The tests that I added are:
@patrickfournier thanks for the code comments, I'll address those later, I'm all out of steam for today. |
…rns None as requested.
|
@patrickfournier thank you again for your comments. I hopefully addressed everything - see below.
I've added this syntax to the tests.
Added a test for this. This case was actually not covered, so I added this functionality.
Test added.
Test added.
Test added. This case was also not covered yet in the code, but i'ts supported now.
Already covered in earlier commits. Regarding your code comments / change requests - I think I covered everything in the last couple of commits. There is a fallback now when get_target_format() returns None, which was the major point. I commented the other points directly. |
patrickfournier
left a comment
There was a problem hiding this comment.
Thanks for the fixes and the doc.
Unless I am mistaken, I think there are still two cases where we do not correctly fallback on output-format.
I also added a request for change in the test code, and a few corrections to the README. English is not my native language, so someone else should review this as well.
| elif isinstance(default[1], list): | ||
| elif isinstance(default[1], (list, tuple)): | ||
| default_item_name = "default" | ||
| default_item_format = get_target_format(default[1]) |
There was a problem hiding this comment.
I do not think this comment is addressed. If we have:
"picture_formats": {
"type": "picture",
"sources": [
{
"name": "webp-src",
"output-format": "webp",
"srcset": [
("640w", ["scale_in 640 480 True"]),
("1024w", ["scale_in 1024 768 True"]),
],
},
],
"default": ("webp-src", ["scale_in 500 500 True"]),
},
default_item_format will not fallback to webp from output-format.
| elif isinstance(default[1], list): | ||
| elif isinstance(default[1], (list, tuple)): | ||
| default_item_name = "default" | ||
| default_item_format = get_target_format(default[1]) |
There was a problem hiding this comment.
I do not think this comment is addressed. See https://github.com/pelican-plugins/image-process/pull/102/changes#r3083171388
| transform_config = COMPLEX_FORMAT_TRANSFORMS[transform_id] | ||
| for url in urls: | ||
| ext = Path(url).suffix.lower() | ||
| expected_ext = self._determine_expected_ext( |
There was a problem hiding this comment.
Instead of having code to find the expected extension, we should have an explicit dict {transform_id1: [file1, file2, ...], ...} of expected file names.
The reason is, currently, the test is testing that _determine_expected_ext achieves the same result as harvest_images_in_fragment. It tests both the plugin code and the test code. If there is a mismatch, we need to hunt for the bug at both places. If we change the plugin code, we need to change the (not so simple) test code. An explicit list would be much easier to maintain.
| this example, it will use the image `640w` from the source `default`. | ||
| A list of operations could have been specified instead of `640w`. | ||
|
|
||
| Similar to `responsive image` described above, also `<picture>` allows the |
There was a problem hiding this comment.
| Similar to `responsive image` described above, also `<picture>` allows the | |
| Similar to `responsive image` described above, `<picture>` also allows the |
|
|
||
| ### Image File Formats | ||
|
|
||
| *Image Process* uses python's pillow library (PIL) to read and write files. The |
There was a problem hiding this comment.
| *Image Process* uses python's pillow library (PIL) to read and write files. The | |
| *Image Process* uses Python's Pillow library (PIL) to read and write files. The |
| ### Image File Formats | ||
|
|
||
| *Image Process* uses python's pillow library (PIL) to read and write files. The | ||
| file formats, that pillow can read and write depend on libraries/plugins that |
There was a problem hiding this comment.
| file formats, that pillow can read and write depend on libraries/plugins that | |
| file formats that Pillow can read and write depend on libraries/plugins that |
| `webp`), uncommon formats may cause issues depending on the system you are | ||
| working on. | ||
|
|
||
| To specify an image format for the derivative image, pillow will infer the image |
There was a problem hiding this comment.
| To specify an image format for the derivative image, pillow will infer the image | |
| To specify an image format for the derivative image, Pillow will infer the image |
|
|
||
| The *SVG* image format is omitted on purpose from the list above; it is a | ||
| *vector* image format (as opposed to the others, which are *raster* formats), | ||
| that is best used for logos and illustrations and you should not blindly convert |
There was a problem hiding this comment.
| that is best used for logos and illustrations and you should not blindly convert | |
| that is best used for logos and illustrations. You should not blindly convert |
Pull request for #101
Feature implemented with new configuration options as proposed by @patrickfournier in #101 (comment).
The implementation of the feature caused two functions to get too long for the linter, so I had to refactor them into smaller chunks, which is why this PR got a bit heavy even though I made no unrelated changes. I added a new test file to test the format conversion and also did a limited manual test in an actual pelican project, though some more thorough testing probably won't hurt.
The entire setup is backwards-compatible, so if you don't change any settings, you'll end up with the same results as in the earlier version.
Hope this is useful - feel free to comment and change whatever needs commenting and changing.