Repository navigation
Media: Use imageflip() in WP_Image_Editor_GD::flip(). #13920
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
e3f315c
086e1d9
45cc763
85eb6d2
5125d15
5adb419
2fd362a
50b71d4
6006322
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -432,31 +432,59 @@ public function rotate( $angle ) { | |||||||||||||||||||||||||||
| * Flips current image. | ||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||
| * @since 3.5.0 | ||||||||||||||||||||||||||||
| * @since 7.2.0 Switched to using imageflip() instead of imagecopyresampled() with negative dimensions. | ||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||
| * @param bool $horz Flip along Horizontal Axis. | ||||||||||||||||||||||||||||
| * @param bool $vert Flip along Vertical Axis. | ||||||||||||||||||||||||||||
| * @return true|WP_Error | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
| public function flip( $horz, $vert ) { | ||||||||||||||||||||||||||||
| $w = $this->size['width']; | ||||||||||||||||||||||||||||
| $h = $this->size['height']; | ||||||||||||||||||||||||||||
| $dst = wp_imagecreatetruecolor( $w, $h ); | ||||||||||||||||||||||||||||
| if ( ! is_gd_image( $this->image ) ) { | ||||||||||||||||||||||||||||
| return new WP_Error( 'image_flip_error', __( 'Image flip failed.' ), $this->file ); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if ( is_gd_image( $dst ) ) { | ||||||||||||||||||||||||||||
| $sx = $vert ? ( $w - 1 ) : 0; | ||||||||||||||||||||||||||||
| $sy = $horz ? ( $h - 1 ) : 0; | ||||||||||||||||||||||||||||
| $sw = $vert ? -$w : $w; | ||||||||||||||||||||||||||||
| $sh = $horz ? -$h : $h; | ||||||||||||||||||||||||||||
| /* | ||||||||||||||||||||||||||||
| * imageflip() works in place and keeps palette images as palette images. | ||||||||||||||||||||||||||||
| * The previous implementation always copied into a new truecolor image, | ||||||||||||||||||||||||||||
| * and saving or streaming as WebP relies on that, since imagewebp() | ||||||||||||||||||||||||||||
| * rejects palette images. Convert first to keep that behavior. | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
| if ( ! imageistruecolor( $this->image ) && ! imagepalettetotruecolor( $this->image ) ) { | ||||||||||||||||||||||||||||
| return new WP_Error( 'image_flip_error', __( 'Image flip failed.' ), $this->file ); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if ( imagecopyresampled( $dst, $this->image, 0, 0, $sx, $sy, $w, $h, $sw, $sh ) ) { | ||||||||||||||||||||||||||||
| if ( PHP_VERSION_ID < 80000 ) { // imagedestroy() has no effect as of PHP 8.0. | ||||||||||||||||||||||||||||
| imagedestroy( $this->image ); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| /* | ||||||||||||||||||||||||||||
| * imageflip() also keeps the current alpha settings, which rotate() leaves | ||||||||||||||||||||||||||||
| * with blending enabled. Reset them to what the previous implementation | ||||||||||||||||||||||||||||
| * always produced, including when no axis is flipped. | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
| imagealphablending( $this->image, false ); | ||||||||||||||||||||||||||||
| imagesavealpha( $this->image, true ); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like there's one more change in how images are handled with GD. Today in
In this PR the image now flips in place, which preserves the source file's values. While this is arguably better and more correct, the current behavior should be preserved after these changes until this can be properly considered and all operations can be updated to behave the same. This should ensure that flip operations perform the same:
Suggested change
|
||||||||||||||||||||||||||||
| $this->image = $dst; | ||||||||||||||||||||||||||||
| /* | ||||||||||||||||||||||||||||
| * imageflip() changes the image in place, so the image keeps its current resolution and interlace setting. | ||||||||||||||||||||||||||||
| * rotate(), crop() and resize() copy into a new image, which resets them to GD's defaults: 96 DPI and no | ||||||||||||||||||||||||||||
| * interlacing. Reset them here too, so a flip gives the same result as the other edits. | ||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||
| * @link https://core.trac.wordpress.org/ticket/66113 | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
| imageresolution( $this->image, 96, 96 ); | ||||||||||||||||||||||||||||
| imageinterlace( $this->image, 0 ); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| if ( ! $horz && ! $vert ) { | ||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if ( $horz && $vert ) { | ||||||||||||||||||||||||||||
| $mode = IMG_FLIP_BOTH; | ||||||||||||||||||||||||||||
| } elseif ( $horz ) { | ||||||||||||||||||||||||||||
| $mode = IMG_FLIP_VERTICAL; | ||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||
| $mode = IMG_FLIP_HORIZONTAL; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if ( imageflip( $this->image, $mode ) ) { | ||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| return new WP_Error( 'image_flip_error', __( 'Image flip failed.' ), $this->file ); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same consideration noted for
WP_Image_Editor_GDapplies here as well: