Opened 9 months ago

Last modified 6 weeks ago

#21668 new enhancement

WordPress still does not save jpeg as progressive jpeg

Reported by: _ck_ Owned by:
Priority: normal Milestone: Awaiting Review
Component: Media Version: 3.4.1
Severity: normal Keywords: has-patch needs-testing
Cc: japh@…, mike.schroder@…, dennen@…

Description

Every time WordPress does imagejpeg it should be doing imageinterlace beforehand to set progressive mode, but it's not.

http://php.net/manual/en/function.imageinterlace.php

Progressive jpeg has been supported by ALL browsers since 2001 or so.

progressive demo: http://bbshowcase.org/progressive/

Note that even if an ancient browser is listed somewhere as not rendering progressive, progressive jpeg still will be displayed, simply showing it all at once rather than gradual.

IE6 for example WILL load progressive jpeg, it will just not render it progressively, instead it will load the entire image and then render all at once at the end.

Progressive algorithm will also make slightly smaller jpeg as a side effect in most cases.

ie. in media.php
`
imageinterlace($newimage,1);
imagejpeg( $newimage, ...
`

This update is years overdue.

It might be possible to futureproof this by adding a filter to $newimage before the final imagejpeg. I am uncertain if that would work since filters would not pass $newimage by reference and instead make a copy - while newimage is only a pointer to php/gd memory. Can apply_filters be forced to work somehow by reference instead of a copy? Maybe that should be another feature idea.

Attachments (3)

21668.patch (1.6 KB) - added by SergeyBiryukov 9 months ago.
21668.2.patch (2.0 KB) - added by SergeyBiryukov 9 months ago.
21668.3.diff (1.4 KB) - added by Japh 7 months ago.
Refreshed patch for 3.5

Download all attachments as: .zip

Change History (16)

comment:1 follow-up: ↓ 2   scribu9 months ago

We are currently in the process of adding support for ImageMagick, so not sure if this is still relevant or not: #6821

Last edited 9 months ago by scribu (previous) (diff)

comment:2 in reply to: ↑ 1   _ck_9 months ago

Replying to scribu:

Many servers do not have imagemagick installed, which given the WP install footprint could mean hundreds of thousands of websites.

Why not fix the default mode of WP, considering only 20 characters are needed to be added in three files and do the responsible thing to make the web faster for millions of visitors on all those pages.

Without a filter, there is no way to affect the output image, so changing the core is required. What's interesting is if they added a filter for this or after it, people could even intercept the jpeg output for watermarking, etc.

  • Cc japh@… added

I don't think progressive images should be the default. I also don't really believe the images will get smaller or there is an extra lost of quality.

About being responsible and that this update is overdue is not really helpful for this ticket. I would love to get some more insight in progressive images and if/how this can also effect PNGs and GIFs.

That said a filter is indeed needed and hopefully it is possible with a reference instead of copying.

comment:5 follow-up: ↓ 6   SergeyBiryukov9 months ago

  • Keywords has-patch added

comment:6 in reply to: ↑ 5   _ck_9 months ago

Replying to SergeyBiryukov:

Thanks for making a patch - I would disagree with the patch for wp-admin/includes/image.php because interlace should only be set specifically before imagejpeg and nothing else as gif and png progressive support is spotty.

Basically anywhere imagejpeg is found in WP code, either a filter-by-reference should be done beforehand or imageinterlace set.

I am uncertain if an apply_filters will obey a php function that is declared as function foo(&$var) and really pass it by reference or first make a copy of the variable it's passed and then try to pass that copy by reference to the function. $newimage almost certainly has to be passed by reference and not a copy (but I could be wrong).

We could test this theory easily:
ie. in media.php

add_filter('imagejpeg','setprogressive');
function setprogressive(&$handle) {
  if (function_exists('imageinterlace')) {imageinterlace($handle,1);}
}
...
apply_filters('imagejpeg',$newimage); // no need to return variable if it's by reference?
imagejpeg( $newimage, ...  

If the image produced is progressive, then it works.

Re-did the patch for 3.5 taking into account the wp-image-editor for both GD and Imagick, JPG and PNG.

Japh7 months ago

Refreshed patch for 3.5

  • Keywords needs-testing added
  • Cc mike.schroder@… added
  • Cc dennen@… added

#19931 was marked as a duplicate.

Note: See TracTickets for help on using tickets.