Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions src/wp-includes/class-wp-image-editor-imagick.php
Original file line number Diff line number Diff line change
Expand Up @@ -492,15 +492,24 @@ protected function thumbnail_image( $dst_w, $dst_h, $filter_name = 'FILTER_TRIAN

/*
* To be more efficient, resample large images to 5x the destination size before resizing
* whenever the output size is less that 1/3 of the original image size (1/3^2 ~= .111),
* unless we would be resampling to a scale smaller than 128x128.
* whenever the output size is less than 1/3 of the original image size (1/3^2 ~= 0.111),
* but only when resampling reduces both source dimensions and keeps both dimensions above 128px.
*/
if ( is_callable( array( $this->image, 'sampleImage' ) ) ) {
$resize_ratio = ( $dst_w / $this->size['width'] ) * ( $dst_h / $this->size['height'] );
$source_size = $this->image->getImageGeometry();
$resize_ratio = ( $dst_w / $source_size['width'] ) * ( $dst_h / $source_size['height'] );
$sample_factor = 5;
$sample_width = $dst_w * $sample_factor;
$sample_height = $dst_h * $sample_factor;

if ( $resize_ratio < .111 && ( $dst_w * $sample_factor > 128 && $dst_h * $sample_factor > 128 ) ) {
$this->image->sampleImage( $dst_w * $sample_factor, $dst_h * $sample_factor );
if (
$resize_ratio < 0.111
&& $sample_width > 128
&& $sample_height > 128
&& $sample_width < $source_size['width']
&& $sample_height < $source_size['height']
) {
$this->image->sampleImage( $sample_width, $sample_height );
}
}

Expand Down
93 changes: 93 additions & 0 deletions tests/phpunit/tests/image/editorImagick.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,99 @@ public function test_resize() {
);
}

/**
* Tests that pre-sampling does not upscale the source image.
*
* @ticket 48842
*/
public function test_thumbnail_image_presampling_does_not_upscale() {
$image = new class() {
public $source_size;
public $sample_size;

// phpcs:disable WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
public function getImageGeometry() {
return $this->source_size;
}

public function sampleImage( $width, $height ) {
$this->sample_size = array( $width, $height );
}

public function scaleImage() {
}
// phpcs:enable
};

$editor = new class( null ) extends WP_Image_Editor_Imagick {
public function call_thumbnail_image( $image, $source_size, $editor_size, $destination_size ) {
$image->source_size = array(
'width' => $source_size[0],
'height' => $source_size[1],
);
$image->sample_size = null;
$this->image = $image;
$this->size = array(
'width' => $editor_size[0],
'height' => $editor_size[1],
);

$result = $this->thumbnail_image( $destination_size[0], $destination_size[1], 'FILTER_TRIANGLE', false );

return is_wp_error( $result ) ? $result : $image->sample_size;
}
};

// The ticket's source and destination dimensions must not trigger an upscale.
$this->assertNull(
$editor->call_thumbnail_image(
$image,
array( 10315, 7049 ),
array( 10315, 7049 ),
array( 2560, 1750 )
)
);

// Use current geometry because cropping can make the editor's stored size stale.
$this->assertNull(
$editor->call_thumbnail_image(
$image,
array( 200, 1000 ),
array( 1000, 1000 ),
array( 50, 100 )
)
);

// Skip pre-sampling unless both intermediate dimensions are smaller than the source.
$this->assertNull(
$editor->call_thumbnail_image(
$image,
array( 1500, 1000 ),
array( 1500, 1000 ),
array( 300, 150 )
)
);
$this->assertNull(
$editor->call_thumbnail_image(
$image,
array( 2000, 750 ),
array( 2000, 750 ),
array( 300, 150 )
)
);

// Keep pre-sampling when both intermediate dimensions are smaller than the source.
$this->assertSame(
array( 1500, 750 ),
$editor->call_thumbnail_image(
$image,
array( 4800, 2400 ),
array( 4800, 2400 ),
array( 300, 150 )
)
);
}

/**
* Tests multi_resize() with single image resize and no crop.
*/
Expand Down
Loading