diff --git a/src/Intervention/Image/Image.php b/src/Intervention/Image/Image.php index 1fbcfe9b..2f6afb14 100644 --- a/src/Intervention/Image/Image.php +++ b/src/Intervention/Image/Image.php @@ -186,40 +186,92 @@ class Image /** * Resize current image based on given width/height * - * @param mixed width|height width and height are optional, the not given - * parameter is calculated based on the given + * Width and height are optional, the not given parameter is calculated + * based on the given. The ratio boolean decides whether the resizing + * should keep the image ratio. You can also pass along a boolean to + * prevent the image from being upsized. + * + * @param integer $width The target width for the image + * @param integer $height The target height for the image + * @param boolean $ratio Determines if the image ratio should be preserved + * @param boolean $upsize Determines whether the image can be upsized + * * @return Image */ - public function resize() + public function resize($width = null, $height = null, $ratio = false, $upsize = true) { - $args = func_get_args(); + // Evaluate passed parameters. + $width = isset($width) ? intval($width) : null; + $height = $max_height = isset($height) ? intval($height) : null; + $ratio = $ratio ? true : false; + $upsize = $upsize ? true : false; - if (array_key_exists(0, $args) && is_array($args[0])) { - - // extract 'width' and 'height' - extract(array_only($args[0], array('width', 'height'))); - $width = isset($width) ? intval($width) : null; - $height = isset($height) ? intval($height) : null; - - if ( ! is_null($width) OR ! is_null($height)) { - // if width or height are not set, define values automatically - $width = is_null($width) ? intval($height / $this->height * $this->width) : $width; - $height = is_null($height) ? intval($width / $this->width * $this->height) : $height; - } else { - // width or height not defined (resume with original values) - throw new Exception('Width or Height needs to be defined as keys in paramater array'); + // If the ratio needs to be kept. + if ($ratio) { + // If both width and hight have been passed along, the width and + // height parameters are maximum values. + if ( ! is_null($width) && ! is_null($height)) { + // First, calculate the height. + $height = intval($width / $this->width * $this->height); + + // If the height is too large, set it to the maximum + // height and calculate the width. + if ($height > $max_height) { + $height = $max_height; + $width = intval($height / $this->height * $this->width); + } } - } elseif (array_key_exists(0, $args) && array_key_exists(1, $args) && is_numeric($args[0]) && is_numeric($args[1])) { - $width = intval($args[0]); - $height = intval($args[1]); + // If only one of width or height has been provided. + else if ($ratio && ( ! is_null($width) OR ! is_null($height))) { + $width = is_null($width) ? intval($height / $this->height * $this->width) : $width; + $height = is_null($height) ? intval($width / $this->width * $this->height) : $height; + } } - if (is_null($width) OR is_null($height)) { + // If the image can't be upsized, check if the given width and/or + // height are too large. + if ( ! $upsize) { + // If the given width is larger then the image width, + // then don't resize it. + if ( ! is_null($width) && $width > $this->width) { + $width = $this->width; + + // If ratio needs to be kept, height is recalculated. + if ($ratio) { + $height = intval($width / $this->width * $this->height); + } + } + + // If the given height is larger then the image height, + // then don't resize it. + if ( ! is_null($height) && $height > $this->height) { + $height = $this->height; + + // If ratio needs to be kept, width is recalculated. + if ($ratio) { + $width = intval($height / $this->height * $this->width); + } + } + } + + // If both the width and height haven't been passed along, + // throw an exception. + if (is_null($width) && is_null($height)) { throw new Exception('width or height needs to be defined'); } - // create new image in new dimensions + // If only the width hasn't been set, keep the current width. + else if (is_null($width) ) { + $width = $this->width; + } + + // If only the height hasn't been set, keep the current height. + else if (is_null($height) ) { + $height = $this->height; + } + + // Create new image in new dimensions. return $this->modify(0, 0, 0, 0, $width, $height, $this->width, $this->height); } diff --git a/tests/ImageTest.php b/tests/ImageTest.php index 7475df06..5359ad5a 100644 --- a/tests/ImageTest.php +++ b/tests/ImageTest.php @@ -38,9 +38,29 @@ class ImageTest extends PHPUnit_Framework_Testcase $this->assertEquals($img->width, 320); $this->assertEquals($img->height, 240); + // Only resize the width. + $img = $this->getTestImage(); + $img->resize(320); + $height = $img->height; + $this->assertInternalType('int', $img->width); + $this->assertInternalType('int', $img->height); + $this->assertEquals($img->width, 320); + // Check if the height is still the same. + $this->assertEquals($img->height, $height); + + // Only resize the width. + $img = $this->getTestImage(); + $img->resize(null, 240); + $width = $img->width; + $this->assertInternalType('int', $img->width); + $this->assertInternalType('int', $img->height); + // Check if the width is still the same. + $this->assertEquals($img->width, $width); + $this->assertEquals($img->height, 240); + // auto height $img = $this->getTestImage(); - $img->resize(array('width' => '320')); + $img->resize(320, null, true); $this->assertInternalType('int', $img->width); $this->assertInternalType('int', $img->height); $this->assertEquals($img->width, 320); @@ -48,11 +68,27 @@ class ImageTest extends PHPUnit_Framework_Testcase // auto width $img = $this->getTestImage(); - $img->resize(array('height' => '240')); + $img->resize(null, 240, true); $this->assertInternalType('int', $img->width); $this->assertInternalType('int', $img->height); $this->assertEquals($img->width, 320); $this->assertEquals($img->height, 240); + + // Test image upsizing. + $img = $this->getTestImage(); + // Keep original width and height. + $original_width = $img->width; + $original_height = $img->height; + // Increase values a bit. + $width = $original_width + 500; + $height = $original_height + 350; + // Try resizing to higher values while upsizing is set to false. + $img->resize($width, $height, false, false); + $this->assertInternalType('int', $img->width); + $this->assertInternalType('int', $img->height); + // Check if width and height are still the same. + $this->assertEquals($img->width, $original_width); + $this->assertEquals($img->height, $original_height); } public function testGrabImage()