<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[59473] trunk: Media: improve filter to enable setting output quality by image size.</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/59473">59473</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/59473","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>adamsilverstein</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2024-11-29 23:46:50 +0000 (Fri, 29 Nov 2024)</dd>
</dl>
<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Media: improve filter to enable setting output quality by image size.
Add a new $size parameter to the wp_editor_set_quality filter. $size is an array with 'width' and 'height' keys. Developers can use this information to set image quality based on the image size.
Props adamsilverstein, joemcgill, Mte90, codekraft, birgire, azaozz, sppramodh.
Fixes <a href="https://core.trac.wordpress.org/ticket/54648">#54648</a>.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesclasswpimageeditorgdphp">trunk/src/wp-includes/class-wp-image-editor-gd.php</a></li>
<li><a href="#trunksrcwpincludesclasswpimageeditorimagickphp">trunk/src/wp-includes/class-wp-image-editor-imagick.php</a></li>
<li><a href="#trunksrcwpincludesclasswpimageeditorphp">trunk/src/wp-includes/class-wp-image-editor.php</a></li>
<li><a href="#trunktestsphpunittestsmediaphp">trunk/tests/phpunit/tests/media.php</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesclasswpimageeditorgdphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/class-wp-image-editor-gd.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-image-editor-gd.php 2024-11-29 22:44:36 UTC (rev 59472)
+++ trunk/src/wp-includes/class-wp-image-editor-gd.php 2024-11-29 23:46:50 UTC (rev 59473)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -221,6 +221,14 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->set_quality(
+ null,
+ array(
+ 'width' => $dst_w,
+ 'height' => $dst_h,
+ )
+ );
+
</ins><span class="cx" style="display: block; padding: 0 10px"> $resized = wp_imagecreatetruecolor( $dst_w, $dst_h );
</span><span class="cx" style="display: block; padding: 0 10px"> imagecopyresampled( $resized, $this->image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -568,12 +576,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * Sets Image Compression quality on a 1-100% scale. Handles WebP lossless images.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 6.7.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 6.8.0 The `$dims` parameter was added.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param int $quality Compression Quality. Range: [1,100]
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param int $quality Compression Quality. Range: [1,100]
+ * @param array $dims Optional. Image dimensions array with 'width' and 'height' keys.
</ins><span class="cx" style="display: block; padding: 0 10px"> * @return true|WP_Error True if set successfully; WP_Error on failure.
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function set_quality( $quality = null ) {
- $quality_result = parent::set_quality( $quality );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function set_quality( $quality = null, $dims = array() ) {
+ $quality_result = parent::set_quality( $quality, $dims );
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( is_wp_error( $quality_result ) ) {
</span><span class="cx" style="display: block; padding: 0 10px"> return $quality_result;
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -586,7 +596,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $webp_info = wp_get_webp_info( $this->file );
</span><span class="cx" style="display: block; padding: 0 10px"> if ( ! empty( $webp_info['type'] ) && 'lossless' === $webp_info['type'] ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $quality = IMG_WEBP_LOSSLESS;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- parent::set_quality( $quality );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ parent::set_quality( $quality, $dims );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> } catch ( Exception $e ) {
</span></span></pre></div>
<a id="trunksrcwpincludesclasswpimageeditorimagickphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/class-wp-image-editor-imagick.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-image-editor-imagick.php 2024-11-29 22:44:36 UTC (rev 59472)
+++ trunk/src/wp-includes/class-wp-image-editor-imagick.php 2024-11-29 23:46:50 UTC (rev 59473)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -190,12 +190,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * Sets Image Compression quality on a 1-100% scale.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 3.5.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 6.8.0 The `$dims` parameter was added.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param int $quality Compression Quality. Range: [1,100]
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param int $quality Compression Quality. Range: [1,100]
+ * @param array $dims Optional. Image dimensions array with 'width' and 'height' keys.
</ins><span class="cx" style="display: block; padding: 0 10px"> * @return true|WP_Error True if set successfully; WP_Error on failure.
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function set_quality( $quality = null ) {
- $quality_result = parent::set_quality( $quality );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function set_quality( $quality = null, $dims = array() ) {
+ $quality_result = parent::set_quality( $quality, $dims );
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( is_wp_error( $quality_result ) ) {
</span><span class="cx" style="display: block; padding: 0 10px"> return $quality_result;
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -367,6 +369,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return $this->crop( $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->set_quality(
+ null,
+ array(
+ 'width' => $dst_w,
+ 'height' => $dst_h,
+ )
+ );
+
</ins><span class="cx" style="display: block; padding: 0 10px"> // Execute the resize.
</span><span class="cx" style="display: block; padding: 0 10px"> $thumb_result = $this->thumbnail_image( $dst_w, $dst_h );
</span><span class="cx" style="display: block; padding: 0 10px"> if ( is_wp_error( $thumb_result ) ) {
</span></span></pre></div>
<a id="trunksrcwpincludesclasswpimageeditorphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/class-wp-image-editor.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-image-editor.php 2024-11-29 22:44:36 UTC (rev 59472)
+++ trunk/src/wp-includes/class-wp-image-editor.php 2024-11-29 23:46:50 UTC (rev 59473)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -240,11 +240,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * Sets Image Compression quality on a 1-100% scale.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 3.5.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 6.8.0 The `$dims` parameter was added.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param int $quality Compression Quality. Range: [1,100]
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param int $quality Compression Quality. Range: [1,100]
+ * @param array $dims Optional. Image dimensions array with 'width' and 'height' keys.
</ins><span class="cx" style="display: block; padding: 0 10px"> * @return true|WP_Error True if set successfully; WP_Error on failure.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function set_quality( $quality = null ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function set_quality( $quality = null, $dims = array() ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> // Use the output mime type if present. If not, fall back to the input/initial mime type.
</span><span class="cx" style="display: block; padding: 0 10px"> $mime_type = ! empty( $this->output_mime_type ) ? $this->output_mime_type : $this->mime_type;
</span><span class="cx" style="display: block; padding: 0 10px"> // Get the default quality setting for the mime type.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -260,11 +263,18 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * The WP_Image_Editor::set_quality() method has priority over the filter.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @since 3.5.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 6.8.0 Added the size parameter.
</ins><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @param int $quality Quality level between 1 (low) and 100 (high).
</span><span class="cx" style="display: block; padding: 0 10px"> * @param string $mime_type Image mime type.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param array $size {
+ * Dimensions of the image.
+ *
+ * @type int $width The image width.
+ * @type int $height The image height.
+ * }
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $quality = apply_filters( 'wp_editor_set_quality', $default_quality, $mime_type );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $quality = apply_filters( 'wp_editor_set_quality', $default_quality, $mime_type, $dims ? $dims : $this->size );
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ( 'image/jpeg' === $mime_type ) {
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span></span></pre></div>
<a id="trunktestsphpunittestsmediaphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/media.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/media.php 2024-11-29 22:44:36 UTC (rev 59472)
+++ trunk/tests/phpunit/tests/media.php 2024-11-29 23:46:50 UTC (rev 59473)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -5434,6 +5434,51 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Test that the `wp_editor_set_quality` filter includes the dimensions in the `$dims` parameter.
+ *
+ * @ticket 54648
+ */
+ public function test_wp_editor_set_quality_includes_dimensions() {
+ // Before loading an image, set up the callback filter with the assertions.
+ add_filter( 'wp_editor_set_quality', array( $this, 'assert_dimensions_in_wp_editor_set_quality' ), 10, 3 );
+
+ $temp_dir = get_temp_dir();
+ $file = $temp_dir . '/33772.jpg';
+ copy( DIR_TESTDATA . '/images/33772.jpg', $file );
+
+ $editor = wp_get_image_editor( $file );
+
+ $attachment_id = self::factory()->attachment->create_object(
+ array(
+ 'post_mime_type' => 'image/jpeg',
+ 'file' => $file,
+ )
+ );
+
+ // Generate all sizes.
+ wp_generate_attachment_metadata( $attachment_id, $file );
+
+ // Clean up the filter.
+ remove_filter( 'wp_editor_set_quality', array( $this, 'assert_dimensions_in_wp_editor_set_quality' ), 10, 3 );
+ }
+
+ /**
+ * Helper callback to assert that the dimensions are included in the `$dims` parameter.
+ *
+ * @param int $quality The quality level.
+ * @param array $dims The dimensions array.
+ */
+ public function assert_dimensions_in_wp_editor_set_quality( $quality, $mime_type, $dims ) {
+ // Assert that the array has non empty width and height values.
+ $this->assertArrayHasKey( 'width', $dims );
+ $this->assertArrayHasKey( 'height', $dims );
+ $this->assertGreaterThan( 0, $dims['width'] );
+ $this->assertGreaterThan( 0, $dims['height'] );
+
+ return $quality;
+ }
+
+ /**
</ins><span class="cx" style="display: block; padding: 0 10px"> * Test that an image size isn't generated if it matches the original image size.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @ticket 57370
</span></span></pre>
</div>
</div>
</body>
</html>