Repository navigation
When uploading, generate both WebP and jpeg format images by default #142
Copy link
Copy link
Closed
Labels
[Plugin] Modern Image FormatsFormerly WebP Uploads [slug: webp-uploads]Formerly WebP Uploads [slug: webp-uploads][Type] EnhancementA suggestion for improvement of an existing featureA suggestion for improvement of an existing feature
Milestone
Description
Feature Description
Based on the decision in #96 (comment) we need to work on enabling generating both formats by default.
Specifically we need to address:
1. When the user uploads a JPEG image, we generate the smaller image sizes in both JPEG and WebP by default.
2. When inserting an image into a post or including an image in the frontend through any other means, we use the WebP version whenever it is available.
3. Developers can opt out of generating JPEG or WebP, e.g. if they are certain they won't need one of these versions.
- Generate both formats
- We can hook on
wp_generate_attachment_metadatato generate the additional mime type images (some example code from @erikyo). - If the user uploads a jpeg and generates jpeg sub sizes, we would hook in and also generate WebP sizes. If the user uploads a WebP core will generate WebP sub sizes, we would hook in and generate jpeg sub sizes
- The behavior should be filterable, I propose a new filter named
image_editor_output_formatswhich would return an array of mime types. By default this would return['image/webp', 'image/jpeg'].- The first/default mime type would be used for the default sub-sizes generated by default and stored in the
sizesarray (If only one mime type is given, only that type is generated). - When more than one mime type is returned, the second and subsequent types are used to generate additional sub sizes and their data stored in the
additional_sizesarray...
- The first/default mime type would be used for the default sub-sizes generated by default and stored in the
1b. In addition to generating the new images, we also need to store meta data for new mime type sizes
- for backwards compatibility reasons, I suggest we store a single mime type in the
sizesarray additional mime type sizes we generate should be stored separately, in a key I propose namingadditional_sizes- mime type data will go into a
sourcesarray inside each size - additional handling will be required for these additional sizes:
- when the original image is deleted, these sub sizes should also be deleted
- when missing sub sizes are regenerated, this should include all mime types
- when the image is cropped/rotated/flipped in the media library, the action should apply to these images as well
- eventually, functions should be extended or added that leverage these new sizes to generate a
pictureelement
- Use WebP on front end
- This can be achieved by having the default
sizessub sizes be WebP by default, which will be the case with['image/webp', 'image/jpeg']as the default value forimage_editor_output_formats - We should also consider adding a mime type argument or a filter for functions like
get_image_tagorwp_get_attachment_image_srcas a more direct way for developers to specify the mime type they want to use.
- Developers can opt out
- Adding
add_filter( 'image_editor_output_formats', '__return_false' );would ensure only the uploaded mime type would be use for sub sizes (current WordPress behavior). - Adding
add_filter( 'image_editor_output_formats', function() { return array( 'image/jpeg', 'image/webp' ); } );would ensure jpeg and WebP were generated, with jpeg stored insizesand used as the default output format - Adding
add_filter( 'image_editor_output_formats', function() { return array( 'image/webp' ); } );would ensure only WebP sub sizes were generated (current behavior of thewebp-uploadsmodule). - The filter will reference the original image for context, so output formats could be dynamic
Feedback welcome as well as contributions, please let us know what you plan to work on by leaving a comment.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
[Plugin] Modern Image FormatsFormerly WebP Uploads [slug: webp-uploads]Formerly WebP Uploads [slug: webp-uploads][Type] EnhancementA suggestion for improvement of an existing featureA suggestion for improvement of an existing feature
Activity
adamsilverstein commentedon Feb 1, 2022
One important note here: based on #75 (comment) we need to ensure that both the image
srcandsrcsetuse the mime type we want to display to ensure that mime type is actually loaded (in some cases, the browser might load thesrcimage). this suggests the possibility of a filter on the output side as well.adamsilverstein commentedon Feb 1, 2022
I'm going to work on a PR for the generating images part.
adamsilverstein commentedon Feb 2, 2022
Good suggestion from @nosilver4u on slack:
we should generate a full sized image in the output mime type (if it doesn't match the original image mime type).
For example, if you uploaded 'file.jpeg', for images below
big_image_size_thresholdwe would store a 'file-webp.webp' version of the full sized image; for larger thanbig_image_size_thresholdfiles where WordPress is creating a '-scaled' version, we should also create a-webpversion of the scaled image. These full sized images could then be used in place of the original or -scaled images for the imgsrctag.nosilver4u commentedon Feb 2, 2022
With #143 in mind, if folks use this:
add_filter( 'image_editor_output_formats', function() { return array( 'image/webp' ); } );Then it seems the full-size should be stored in the WebP format whether it's above
big_image_size_thresholdor not.Does that potentially cause issues where images over 2560 have
-scaled, and those under 2560 have-webpin the filename? Or is it irrelevant so long as the proper path/filename is stored in the attachment metadata?adamsilverstein commentedon Feb 2, 2022
in spots like the media library or certain functions, we may still want to treat the file matching the uploaded mime type as the "original" file. so even though there is a full size WebP image, if you go to the media editor, it will use the full size jpeg image (assuming you start with a jpeg upload... that would be the original or a file with -scaled appended).
Add the `sources` property to each image size
mitogh commentedon Feb 3, 2022
Created a draft version for a
sourcesproperty approach @adamsilversteinsourcesfor storage. #1476 remaining items
mitogh commentedon Feb 8, 2022
Thanks @adamsilverstein , I'm using the recommended hook
wp_generate_attachment_metadata:_wp_attachment_backup_sizes#154However, there might be other cases that we need to cover like when the image is rotated or cropped should we need to support the same backup mechanism for this type of edit. And this hook is not fired in those scenarios so an update would be required to the PR above to take into account those type of modifications to the original image from within the WordPress editor.
I'm opening a new issue for this describing the behavior so we can discuss the alternatives here but replicating what core does for the original image on additional mime types seems like the right path here.
adamsilverstein commentedon Feb 9, 2022
Right - we will probably need to handle these explicitly.
adamsilverstein commentedon Feb 11, 2022
Quick update on this issue: I have been researching approaches to async image generation and digging into the core cropping behavior.
_wp_attachment_backup_sizesif we wind up using that approach. It is used inwp_crop_imageand alsowp_restore_imageand a few other places. I reviewed these and they seem to stick to expecting a specific suffix so should be okwp.Uploaderto fire a callback shortly after the initial callback completes, this allows us to pass the attachment id to the callback as well. example https://gist.github.com/adamsilverstein/9b384db1ff9f596e465712cdb6d017d3 - code could include retries similar to core missing mages regeneration on errors. we will have to test if this works in Gutenberg or add an alternate implementation thereSplit the edit logic into a separate Pull Request
Add support for multiple mime types for existing images sizes.
mitogh commentedon Feb 22, 2022
Ready for review:
sourcesfor storage. #147Please take a look at the code above and provide any feedback on the code or the feature itself, give it a try locally and let us know in case something is not working as expected.
felixarntz commentedon Feb 24, 2022
Reopening because support for the retry mechanism still has to be added (already underway in #188).
felixarntz commentedon Feb 25, 2022
Fixed via #147 and #188 🎉