diff --git a/lib/Imagine/Filter/Basic/Save.php b/lib/Imagine/Filter/Basic/Save.php index dc87148d1..0f76625a1 100644 --- a/lib/Imagine/Filter/Basic/Save.php +++ b/lib/Imagine/Filter/Basic/Save.php @@ -35,7 +35,7 @@ class Save implements FilterInterface * @param string $path * @param array $options */ - public function __construct($path, array $options = array()) + public function __construct($path = null, array $options = array()) { $this->path = $path; $this->options = $options; diff --git a/lib/Imagine/Filter/Transformation.php b/lib/Imagine/Filter/Transformation.php index 5590bd1a3..dff0a746d 100644 --- a/lib/Imagine/Filter/Transformation.php +++ b/lib/Imagine/Filter/Transformation.php @@ -180,7 +180,7 @@ public function rotate($angle, ColorInterface $background = null) /** * {@inheritdoc} */ - public function save($path, array $options = array()) + public function save($path = null, array $options = array()) { return $this->add(new Save($path, $options)); } diff --git a/lib/Imagine/Gd/Image.php b/lib/Imagine/Gd/Image.php index 1256ea1d4..a5e2cc602 100644 --- a/lib/Imagine/Gd/Image.php +++ b/lib/Imagine/Gd/Image.php @@ -43,6 +43,13 @@ final class Image implements ImageInterface */ private $palette; + /** + * Path to original source file + * + * @var null|string + */ + private $path; + /** * Constructs a new Image instance using the result of * imagecreatetruecolor() @@ -50,10 +57,11 @@ final class Image implements ImageInterface * @param resource $resource * @param PaletteInterface $palette */ - public function __construct($resource, PaletteInterface $palette) + public function __construct($resource, PaletteInterface $palette, $path = null) { $this->palette = $palette; $this->resource = $resource; + $this->path = $path; } /** @@ -213,8 +221,16 @@ final public function rotate($angle, ColorInterface $background = null) /** * {@inheritdoc} */ - final public function save($path, array $options = array()) + final public function save($path = null, array $options = array()) { + $path = null === $path ? $this->path : $path; + + if (null === $path) { + throw new RuntimeException( + 'You can ommit save path only if image has been open from a file' + ); + } + $format = isset($options['format']) ? $options['format'] : pathinfo($path, \PATHINFO_EXTENSION); diff --git a/lib/Imagine/Gd/Imagine.php b/lib/Imagine/Gd/Imagine.php index 7e33e36a1..583ad1baf 100644 --- a/lib/Imagine/Gd/Imagine.php +++ b/lib/Imagine/Gd/Imagine.php @@ -103,22 +103,21 @@ public function create(BoxInterface $size, ColorInterface $color = null) */ public function open($path) { - $handle = @fopen($path, 'r'); + $data = @file_get_contents($path); - if (false === $handle) { + if (false === $data) { throw new InvalidArgumentException(sprintf( 'File %s doesn\'t exist', $path )); } - try { - $image = $this->read($handle); - } catch (\Exception $e) { - fclose($handle); - throw new RuntimeException(sprintf('Unable to open image %s', $path), $e->getCode(), $e); + $resource = @imagecreatefromstring($data); + + if (!is_resource($resource)) { + throw new InvalidArgumentException(sprintf('Unable to open image %s', $path)); } - return $image; + return $this->wrap($resource, new RGB(), $path); } /** @@ -165,7 +164,7 @@ public function font($file, $size, ColorInterface $color) return new Font($file, $size, $color); } - private function wrap($resource, PaletteInterface $palette) + private function wrap($resource, PaletteInterface $palette, $path = null) { if (!imageistruecolor($resource)) { list($width, $height) = array(imagesx($resource), imagesy($resource)); @@ -194,6 +193,6 @@ private function wrap($resource, PaletteInterface $palette) imageantialias($resource, true); } - return new Image($resource, $palette); + return new Image($resource, $palette, $path); } } diff --git a/lib/Imagine/Gmagick/Image.php b/lib/Imagine/Gmagick/Image.php index f1a880b61..33adeedf5 100644 --- a/lib/Imagine/Gmagick/Image.php +++ b/lib/Imagine/Gmagick/Image.php @@ -300,8 +300,14 @@ private function applyImageOptions(\Gmagick $image, array $options) /** * {@inheritdoc} */ - public function save($path, array $options = array()) + public function save($path = null, array $options = array()) { + if (null === $path) { + throw new RuntimeException( + 'Gmagick bug #65297 prevents to save without a path' + ); + } + try { $this->prepareOutput($options); $allFrames = !isset($options['animated']) || false === $options['animated']; diff --git a/lib/Imagine/Image/ManipulatorInterface.php b/lib/Imagine/Image/ManipulatorInterface.php index b1dbf3fb0..a86a403dd 100644 --- a/lib/Imagine/Image/ManipulatorInterface.php +++ b/lib/Imagine/Image/ManipulatorInterface.php @@ -106,7 +106,7 @@ public function paste(ImageInterface $image, PointInterface $start); * * @return ManipulatorInterface */ - public function save($path, array $options = array()); + public function save($path = null, array $options = array()); /** * Outputs the image content diff --git a/lib/Imagine/Imagick/Image.php b/lib/Imagine/Imagick/Image.php index ac61cee71..e6ed2fe99 100644 --- a/lib/Imagine/Imagick/Image.php +++ b/lib/Imagine/Imagick/Image.php @@ -289,11 +289,11 @@ public function rotate($angle, ColorInterface $background = null) /** * {@inheritdoc} */ - public function save($path, array $options = array()) + public function save($path = null, array $options = array()) { try { $this->prepareOutput($options); - $this->imagick->writeImages($path, true); + $this->imagick->writeImage($path); } catch (\ImagickException $e) { throw new RuntimeException( 'Save operation failed', $e->getCode(), $e diff --git a/lib/Imagine/Imagick/Imagine.php b/lib/Imagine/Imagick/Imagine.php index 1c59c7e32..bcb39007c 100644 --- a/lib/Imagine/Imagick/Imagine.php +++ b/lib/Imagine/Imagick/Imagine.php @@ -59,6 +59,7 @@ public function open($path) try { $image = $this->read($handle); + $image->getImagick()->setImageFilename($path); } catch (\Exception $e) { fclose($handle); throw new RuntimeException(sprintf('Unable to open image %s', $path), $e->getCode(), $e); diff --git a/tests/Imagine/Test/Gmagick/ImageTest.php b/tests/Imagine/Test/Gmagick/ImageTest.php index 1cae6bb7a..a595eaa3c 100644 --- a/tests/Imagine/Test/Gmagick/ImageTest.php +++ b/tests/Imagine/Test/Gmagick/ImageTest.php @@ -58,6 +58,17 @@ public function testPaletteIsGrayIfGrayImage() $this->markTestSkipped('Gmagick does not support Gray colorspace, because of the lack omg image type support'); } + /** + * @expectedException Imagine\Exception\RuntimeException + */ + public function testSaveWithoutPathFileFromImageLoadShouldBeOkay() + { + $this + ->getImagine() + ->open(__DIR__ . '/../../Fixtures/google.png') + ->save(); + } + protected function getImagine() { return new Imagine(); diff --git a/tests/Imagine/Test/Image/AbstractImageTest.php b/tests/Imagine/Test/Image/AbstractImageTest.php index db74c2fb2..1e1958b3d 100644 --- a/tests/Imagine/Test/Image/AbstractImageTest.php +++ b/tests/Imagine/Test/Image/AbstractImageTest.php @@ -93,6 +93,36 @@ public function testUsePalette($from, $to, $color) unlink(__DIR__ . '/tmp.jpg'); } + public function testSaveWithoutPathFileFromImageLoadShouldBeOkay() + { + $source = __DIR__ . '/../../Fixtures/google.png'; + $tmpFile = __DIR__ . '/../../Fixtures/google.tmp.png'; + + if (file_exists($tmpFile)) { + unlink($tmpFile); + } + + copy($source, $tmpFile); + + $this->assertEquals(md5_file($source), md5_file($tmpFile)); + + $this + ->getImagine() + ->open($tmpFile) + ->resize(new Box(20, 20)) + ->save(); + + $this->assertNotEquals(md5_file($source), md5_file($tmpFile)); + unlink($tmpFile); + } + + public function testSaveWithoutPathFileFromImageCreationShouldFail() + { + $image = $this->getImagine()->create(new Box(20, 20)); + $this->setExpectedException('Imagine\Exception\RuntimeException'); + $image->save(); + } + public function provideFromAndToPalettes() { return array(