Use `round()` instead of `floor()` when resizing image dimensions.

Updates unit tests.

Props SergeyBiryukov, kitchin.
Fixes #18532.


git-svn-id: https://develop.svn.wordpress.org/trunk@30660 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Scott Taylor 2014-11-30 19:53:18 +00:00
parent dad44082a7
commit 35708f61f8
5 changed files with 104 additions and 78 deletions

View File

@ -379,26 +379,33 @@ function wp_constrain_dimensions( $current_width, $current_height, $max_width=0,
$smaller_ratio = min( $width_ratio, $height_ratio );
$larger_ratio = max( $width_ratio, $height_ratio );
if ( intval( $current_width * $larger_ratio ) > $max_width || intval( $current_height * $larger_ratio ) > $max_height )
if ( (int) round( $current_width * $larger_ratio ) > $max_width || (int) round( $current_height * $larger_ratio ) > $max_height ) {
// The larger ratio is too big. It would result in an overflow.
$ratio = $smaller_ratio;
else
} else {
// The larger ratio fits, and is likely to be a more "snug" fit.
$ratio = $larger_ratio;
}
// Very small dimensions may result in 0, 1 should be the minimum.
$w = max ( 1, intval( $current_width * $ratio ) );
$h = max ( 1, intval( $current_height * $ratio ) );
$w = max ( 1, (int) round( $current_width * $ratio ) );
$h = max ( 1, (int) round( $current_height * $ratio ) );
// Sometimes, due to rounding, we'll end up with a result like this: 465x700 in a 177x177 box is 117x176... a pixel short
// We also have issues with recursive calls resulting in an ever-changing result. Constraining to the result of a constraint should yield the original result.
// Thus we look for dimensions that are one pixel shy of the max value and bump them up
if ( $did_width && $w == $max_width - 1 )
$w = $max_width; // Round it up
if ( $did_height && $h == $max_height - 1 )
$h = $max_height; // Round it up
return array( $w, $h );
// Note: $did_width means it is possible $smaller_ratio == $width_ratio.
if ( $did_width && $w == $max_width - 1 ) {
$w = $max_width; // Round it up
}
// Note: $did_height means it is possible $smaller_ratio == $height_ratio.
if ( $did_height && $h == $max_height - 1 ) {
$h = $max_height; // Round it up
}
return apply_filters( 'wp_constrain_dimensions', array( $w, $h ), $current_width, $current_height, $max_width, $max_height );
}
/**
@ -459,12 +466,12 @@ function image_resize_dimensions($orig_w, $orig_h, $dest_w, $dest_h, $crop = fal
$new_w = min($dest_w, $orig_w);
$new_h = min($dest_h, $orig_h);
if ( !$new_w ) {
$new_w = intval($new_h * $aspect_ratio);
if ( ! $new_w ) {
$new_w = (int) round( $new_h * $aspect_ratio );
}
if ( !$new_h ) {
$new_h = intval($new_w / $aspect_ratio);
if ( ! $new_h ) {
$new_h = (int) round( $new_w / $aspect_ratio );
}
$size_ratio = max($new_w / $orig_w, $new_h / $orig_h);

View File

@ -282,9 +282,9 @@ class Tests_Image_Editor_GD extends WP_Image_UnitTestCase {
// #0
array(
'file' => 'waffles-10x6.jpg',
'file' => 'waffles-10x7.jpg',
'width' => 10,
'height' => 6,
'height' => 7,
'mime-type' => 'image/jpeg',
),
@ -322,16 +322,16 @@ class Tests_Image_Editor_GD extends WP_Image_UnitTestCase {
// #5
array(
'file' => 'waffles-55x36.jpg',
'file' => 'waffles-55x37.jpg',
'width' => 55,
'height' => 36,
'height' => 37,
'mime-type' => 'image/jpeg',
),
// #6
array(
'file' => 'waffles-82x55.jpg',
'width' => 82,
'file' => 'waffles-83x55.jpg',
'width' => 83,
'height' => 55,
'mime-type' => 'image/jpeg',
),

View File

@ -282,9 +282,9 @@ class Tests_Image_Editor_Imagick extends WP_Image_UnitTestCase {
// #0
array(
'file' => 'waffles-10x6.jpg',
'file' => 'waffles-10x7.jpg',
'width' => 10,
'height' => 6,
'height' => 7,
'mime-type' => 'image/jpeg',
),
@ -322,16 +322,16 @@ class Tests_Image_Editor_Imagick extends WP_Image_UnitTestCase {
// #5
array(
'file' => 'waffles-55x36.jpg',
'file' => 'waffles-55x37.jpg',
'width' => 55,
'height' => 36,
'height' => 37,
'mime-type' => 'image/jpeg',
),
// #6
array(
'file' => 'waffles-82x55.jpg',
'width' => 82,
'file' => 'waffles-83x55.jpg',
'width' => 83,
'height' => 55,
'mime-type' => 'image/jpeg',
),

View File

@ -13,7 +13,7 @@ abstract class WP_Tests_Image_Resize_UnitTestCase extends WP_Image_UnitTestCase
function test_resize_jpg() {
$image = $this->resize_helper( DIR_TESTDATA.'/images/test-image.jpg', 25, 25 );
$this->assertEquals( 'test-image-25x25.jpg', basename($image) );
$this->assertEquals( 'test-image-25x25.jpg', basename( $image ) );
list($w, $h, $type) = getimagesize($image);
$this->assertEquals( 25, $w );
$this->assertEquals( 25, $h );
@ -25,7 +25,12 @@ abstract class WP_Tests_Image_Resize_UnitTestCase extends WP_Image_UnitTestCase
function test_resize_png() {
$image = $this->resize_helper( DIR_TESTDATA.'/images/test-image.png', 25, 25 );
$this->assertEquals( 'test-image-25x25.png', basename($image) );
if ( ! is_string( $image ) ) { // WP_Error, stop GLib-GObject-CRITICAL assertion
$this->markTestSkipped( sprintf( 'No PNG support in the editor engine %s on this system', $this->editor_engine ) );
return;
}
$this->assertEquals( 'test-image-25x25.png', basename( $image ) );
list($w, $h, $type) = getimagesize($image);
$this->assertEquals( 25, $w );
$this->assertEquals( 25, $h );
@ -37,7 +42,12 @@ abstract class WP_Tests_Image_Resize_UnitTestCase extends WP_Image_UnitTestCase
function test_resize_gif() {
$image = $this->resize_helper( DIR_TESTDATA.'/images/test-image.gif', 25, 25 );
$this->assertEquals( 'test-image-25x25.gif', basename($image) );
if ( ! is_string( $image ) ) { // WP_Error, stop GLib-GObject-CRITICAL assertion
$this->markTestSkipped( sprintf( 'No GIF support in the editor engine %s on this system', $this->editor_engine ) );
return;
}
$this->assertEquals( 'test-image-25x25.gif', basename( $image ) );
list($w, $h, $type) = getimagesize($image);
$this->assertEquals( 25, $w );
$this->assertEquals( 25, $h );
@ -57,9 +67,9 @@ abstract class WP_Tests_Image_Resize_UnitTestCase extends WP_Image_UnitTestCase
function test_resize_thumb_128x96() {
$image = $this->resize_helper( DIR_TESTDATA.'/images/2007-06-17DSC_4173.JPG', 128, 96 );
$this->assertEquals( '2007-06-17DSC_4173-63x96.jpg', basename($image) );
$this->assertEquals( '2007-06-17DSC_4173-64x96.jpg', basename( $image ) );
list($w, $h, $type) = getimagesize($image);
$this->assertEquals( 63, $w );
$this->assertEquals( 64, $w );
$this->assertEquals( 96, $h );
$this->assertEquals( IMAGETYPE_JPEG, $type );
@ -69,10 +79,10 @@ abstract class WP_Tests_Image_Resize_UnitTestCase extends WP_Image_UnitTestCase
function test_resize_thumb_128x0() {
$image = $this->resize_helper( DIR_TESTDATA.'/images/2007-06-17DSC_4173.JPG', 128, 0 );
$this->assertEquals( '2007-06-17DSC_4173-128x192.jpg', basename($image) );
$this->assertEquals( '2007-06-17DSC_4173-128x193.jpg', basename( $image ) );
list($w, $h, $type) = getimagesize($image);
$this->assertEquals( 128, $w );
$this->assertEquals( 192, $h );
$this->assertEquals( 193, $h );
$this->assertEquals( IMAGETYPE_JPEG, $type );
unlink( $image );
@ -81,9 +91,9 @@ abstract class WP_Tests_Image_Resize_UnitTestCase extends WP_Image_UnitTestCase
function test_resize_thumb_0x96() {
$image = $this->resize_helper( DIR_TESTDATA.'/images/2007-06-17DSC_4173.JPG', 0, 96 );
$this->assertEquals( '2007-06-17DSC_4173-63x96.jpg', basename($image) );
$this->assertEquals( '2007-06-17DSC_4173-64x96.jpg', basename( $image ) );
list($w, $h, $type) = getimagesize($image);
$this->assertEquals( 63, $w );
$this->assertEquals( 64, $w );
$this->assertEquals( 96, $h );
$this->assertEquals( IMAGETYPE_JPEG, $type );
@ -93,7 +103,7 @@ abstract class WP_Tests_Image_Resize_UnitTestCase extends WP_Image_UnitTestCase
function test_resize_thumb_150x150_crop() {
$image = $this->resize_helper( DIR_TESTDATA.'/images/2007-06-17DSC_4173.JPG', 150, 150, true );
$this->assertEquals( '2007-06-17DSC_4173-150x150.jpg', basename($image) );
$this->assertEquals( '2007-06-17DSC_4173-150x150.jpg', basename( $image ) );
list($w, $h, $type) = getimagesize($image);
$this->assertEquals( 150, $w );
$this->assertEquals( 150, $h );
@ -105,7 +115,7 @@ abstract class WP_Tests_Image_Resize_UnitTestCase extends WP_Image_UnitTestCase
function test_resize_thumb_150x100_crop() {
$image = $this->resize_helper( DIR_TESTDATA.'/images/2007-06-17DSC_4173.JPG', 150, 100, true );
$this->assertEquals( '2007-06-17DSC_4173-150x100.jpg', basename($image) );
$this->assertEquals( '2007-06-17DSC_4173-150x100.jpg', basename( $image ) );
list($w, $h, $type) = getimagesize($image);
$this->assertEquals( 150, $w );
$this->assertEquals( 100, $h );
@ -117,7 +127,7 @@ abstract class WP_Tests_Image_Resize_UnitTestCase extends WP_Image_UnitTestCase
function test_resize_thumb_50x150_crop() {
$image = $this->resize_helper( DIR_TESTDATA.'/images/2007-06-17DSC_4173.JPG', 50, 150, true );
$this->assertEquals( '2007-06-17DSC_4173-50x150.jpg', basename($image) );
$this->assertEquals( '2007-06-17DSC_4173-50x150.jpg', basename( $image ) );
list($w, $h, $type) = getimagesize($image);
$this->assertEquals( 50, $w );
$this->assertEquals( 150, $h );
@ -142,6 +152,12 @@ abstract class WP_Tests_Image_Resize_UnitTestCase extends WP_Image_UnitTestCase
* @ticket 6821
*/
public function test_resize_bad_image() {
if ( $this->editor_engine == 'WP_Image_Editor_Imagick' ) {
$this->markTestSkipped( sprintf( 'Avoid GLib-GObject-CRITICAL assertion in %s', $this->editor_engine ) );
return;
}
$image = $this->resize_helper( DIR_TESTDATA.'/export/crazy-cdata.xml', 25, 25 );
$this->assertInstanceOf( 'WP_Error', $image );
$this->assertEquals( 'invalid_image', $image->get_error_code() );

View File

@ -13,13 +13,16 @@ class Tests_Image_Size extends WP_UnitTestCase {
// no constraint - should have no effect
$out = wp_constrain_dimensions(640, 480, 0, 0);
$this->assertEquals(array(640, 480), $out);
$this->assertSame( array( 640, 480 ), $out );
$out = wp_constrain_dimensions(640, 480);
$this->assertEquals(array(640, 480), $out);
$this->assertSame( array( 640, 480 ), $out );
$out = wp_constrain_dimensions(0, 0, 0, 0);
$this->assertEquals(array(0, 0), $out);
$this->assertSame( array( 0, 0 ), $out );
$out = wp_constrain_dimensions(465, 700, 177, 177);
$this->assertSame( array( 118, 177 ), $out );
}
function test_constrain_dims_smaller() {
@ -28,13 +31,13 @@ class Tests_Image_Size extends WP_UnitTestCase {
// image size is smaller than the constraint - no effect
$out = wp_constrain_dimensions(500, 600, 1024, 768);
$this->assertEquals(array(500, 600), $out);
$this->assertSame( array( 500, 600 ), $out );
$out = wp_constrain_dimensions(500, 600, 0, 768);
$this->assertEquals(array(500, 600), $out);
$this->assertSame( array( 500, 600 ), $out );
$out = wp_constrain_dimensions(500, 600, 1024, 0);
$this->assertEquals(array(500, 600), $out);
$this->assertSame( array( 500, 600 ), $out );
}
function test_constrain_dims_equal() {
@ -43,13 +46,13 @@ class Tests_Image_Size extends WP_UnitTestCase {
// image size is equal to the constraint - no effect
$out = wp_constrain_dimensions(1024, 768, 1024, 768);
$this->assertequals(array(1024, 768), $out);
$this->assertSame( array( 1024, 768 ), $out );
$out = wp_constrain_dimensions(1024, 768, 0, 768);
$this->assertequals(array(1024, 768), $out);
$this->assertSame( array( 1024, 768 ), $out );
$out = wp_constrain_dimensions(1024, 768, 1024, 0);
$this->assertequals(array(1024, 768), $out);
$this->assertSame( array( 1024, 768 ), $out );
}
function test_constrain_dims_larger() {
@ -58,23 +61,23 @@ class Tests_Image_Size extends WP_UnitTestCase {
// image size is larger than the constraint - result should be constrained
$out = wp_constrain_dimensions(1024, 768, 500, 600);
$this->assertequals(array(500, 375), $out);
$this->assertSame( array( 500, 375 ), $out );
$out = wp_constrain_dimensions(1024, 768, 0, 600);
$this->assertequals(array(800, 600), $out);
$this->assertSame( array( 800, 600 ), $out );
$out = wp_constrain_dimensions(1024, 768, 500, 0);
$this->assertequals(array(500, 375), $out);
$this->assertSame( array( 500, 375 ), $out );
// also try a portrait oriented image
$out = wp_constrain_dimensions(300, 800, 500, 600);
$this->assertequals(array(225, 600), $out);
$this->assertSame( array( 225, 600 ), $out );
$out = wp_constrain_dimensions(300, 800, 0, 600);
$this->assertequals(array(225, 600), $out);
$this->assertSame( array( 225, 600 ), $out );
$out = wp_constrain_dimensions(300, 800, 200, 0);
$this->assertequals(array(200, 533), $out);
$this->assertSame( array( 200, 533 ), $out );
}
function test_constrain_dims_boundary() {
@ -83,17 +86,17 @@ class Tests_Image_Size extends WP_UnitTestCase {
// one dimension is larger than the constraint, one smaller - result should be constrained
$out = wp_constrain_dimensions(1024, 768, 500, 800);
$this->assertequals(array(500, 375), $out);
$this->assertSame( array( 500, 375 ), $out );
$out = wp_constrain_dimensions(1024, 768, 2000, 700);
$this->assertequals(array(933, 700), $out);
$this->assertSame( array( 933, 700 ), $out );
// portrait
$out = wp_constrain_dimensions(768, 1024, 800, 500);
$this->assertequals(array(375, 500), $out);
$this->assertSame( array( 375, 500 ), $out );
$out = wp_constrain_dimensions(768, 1024, 2000, 700);
$this->assertequals(array(525, 700), $out);
$this->assertSame( array( 525, 700 ), $out );
}
/**
@ -101,10 +104,10 @@ class Tests_Image_Size extends WP_UnitTestCase {
*/
function test_shrink_dimensions_default() {
$out = wp_shrink_dimensions(640, 480);
$this->assertEquals(array(128, 96), $out);
$this->assertSame( array( 128, 96 ), $out );
$out = wp_shrink_dimensions(480, 640);
$this->assertEquals(array(72, 96), $out);
$this->assertSame( array( 72, 96 ), $out );
}
/**
@ -113,10 +116,10 @@ class Tests_Image_Size extends WP_UnitTestCase {
function test_shrink_dimensions_smaller() {
// image size is smaller than the constraint - no effect
$out = wp_shrink_dimensions(500, 600, 1024, 768);
$this->assertEquals(array(500, 600), $out);
$this->assertSame( array( 500, 600 ), $out );
$out = wp_shrink_dimensions(600, 500, 1024, 768);
$this->assertEquals(array(600, 500), $out);
$this->assertSame( array( 600, 500 ), $out );
}
/**
@ -125,10 +128,10 @@ class Tests_Image_Size extends WP_UnitTestCase {
function test_shrink_dimensions_equal() {
// image size is equal to the constraint - no effect
$out = wp_shrink_dimensions(500, 600, 500, 600);
$this->assertEquals(array(500, 600), $out);
$this->assertSame( array( 500, 600 ), $out );
$out = wp_shrink_dimensions(600, 500, 600, 500);
$this->assertEquals(array(600, 500), $out);
$this->assertSame( array( 600, 500 ), $out );
}
/**
@ -137,10 +140,10 @@ class Tests_Image_Size extends WP_UnitTestCase {
function test_shrink_dimensions_larger() {
// image size is larger than the constraint - result should be constrained
$out = wp_shrink_dimensions(1024, 768, 500, 600);
$this->assertequals(array(500, 375), $out);
$this->assertSame( array( 500, 375 ), $out );
$out = wp_shrink_dimensions(300, 800, 500, 600);
$this->assertequals(array(225, 600), $out);
$this->assertSame( array( 225, 600 ), $out );
}
/**
@ -149,25 +152,25 @@ class Tests_Image_Size extends WP_UnitTestCase {
function test_shrink_dimensions_boundary() {
// one dimension is larger than the constraint, one smaller - result should be constrained
$out = wp_shrink_dimensions(1024, 768, 500, 800);
$this->assertequals(array(500, 375), $out);
$this->assertSame( array( 500, 375 ), $out );
$out = wp_shrink_dimensions(1024, 768, 2000, 700);
$this->assertequals(array(933, 700), $out);
$this->assertSame( array( 933, 700 ), $out );
// portrait
$out = wp_shrink_dimensions(768, 1024, 800, 500);
$this->assertequals(array(375, 500), $out);
$this->assertSame( array( 375, 500 ), $out );
$out = wp_shrink_dimensions(768, 1024, 2000, 700);
$this->assertequals(array(525, 700), $out);
$this->assertSame( array( 525, 700 ), $out );
}
function test_constrain_size_for_editor_thumb() {
$out = image_constrain_size_for_editor(600, 400, 'thumb');
$this->assertEquals(array(150, 100), $out);
$this->assertSame( array( 150, 100 ), $out );
$out = image_constrain_size_for_editor(64, 64, 'thumb');
$this->assertEquals(array(64, 64), $out);
$this->assertSame( array( 64, 64 ), $out );
}
function test_constrain_size_for_editor_medium() {
@ -181,18 +184,18 @@ class Tests_Image_Size extends WP_UnitTestCase {
update_option('medium_size_h', 0);
$out = image_constrain_size_for_editor(600, 400, 'medium');
$this->assertEquals(array(500, 333), $out);
$this->assertSame( array( 500, 333 ), $out );
$out = image_constrain_size_for_editor(400, 600, 'medium');
$this->assertEquals(array(400, 600), $out);
$this->assertSame( array( 400, 600 ), $out );
$out = image_constrain_size_for_editor(64, 64, 'medium');
$this->assertEquals(array(64, 64), $out);
$this->assertSame( array( 64, 64 ), $out );
// content_width should be ignored
$content_width = 350;
$out = image_constrain_size_for_editor(600, 400, 'medium');
$this->assertEquals(array(500, 333), $out);
$this->assertSame( array( 500, 333 ), $out );
$content_width = $_content_width;
}
@ -204,19 +207,19 @@ class Tests_Image_Size extends WP_UnitTestCase {
$content_width = 400;
$out = image_constrain_size_for_editor(600, 400, 'full');
$this->assertEquals(array(600, 400), $out);
$this->assertSame( array( 600, 400 ), $out );
$out = image_constrain_size_for_editor(64, 64, 'full');
$this->assertEquals(array(64, 64), $out);
$this->assertSame( array( 64, 64 ), $out );
// content_width default is 500
$content_width = 0;
$out = image_constrain_size_for_editor(600, 400, 'full');
$this->assertEquals(array(600, 400), $out);
$this->assertSame( array( 600, 400 ), $out );
$out = image_constrain_size_for_editor(64, 64, 'full');
$this->assertEquals(array(64, 64), $out);
$this->assertSame( array( 64, 64 ), $out );
$content_width = $_content_width;
}