diff --git a/src/Image/Image.php b/src/Image/Image.php index aa51f56..2eddc5a 100644 --- a/src/Image/Image.php +++ b/src/Image/Image.php @@ -378,76 +378,11 @@ public function save(?string $path = null, string $type = '', int $quality = 75) break; case 'webp': - $temp = null; - $output = null; - try { - if ($quality >= 0) { - $this->image->setImageCompressionQuality($quality); - } - $this->image->setImageFormat('webp'); - - if (empty($path)) { - return $this->image->getImagesBlob(); - } else { - $this->image->writeImages($path, true); - } - } catch (\Throwable) { - $signature = $this->image->getImageSignature(); - - $temp = tempnam(sys_get_temp_dir(), 'temp-'.$signature); - if ($temp === false) { - throw new Exception('Failed to create temporary file'); - } - - $output = tempnam(sys_get_temp_dir(), 'output-'.$signature); - if ($output === false) { - \unlink($temp); - throw new Exception('Failed to create output file'); - } - - $temp .= '.'.\strtolower($this->image->getImageFormat()); - $output .= '.'.$type; - - // save temp - $this->image->writeImages($temp, true); - - // convert temp - $quality = (int) $quality; - $command = \sprintf( - 'cwebp -quiet -metadata none -q %d %s -o %s', - $quality, - \escapeshellarg($temp), - \escapeshellarg($output) - ); - \exec($command, $outputArray, $returnCode); - - if ($returnCode !== 0) { - throw new Exception('Image conversion failed'); - } - - $data = \file_get_contents($output); - - // save to path - if (! empty($path)) { - \file_put_contents($path, $data, LOCK_EX); - - return; - } - - return $data; - } finally { - if (is_string($temp) && file_exists($temp)) { - \unlink($temp); - } - if (is_string($output) && file_exists($output)) { - \unlink($output); - } - - $this->image->clear(); - $this->image->destroy(); + if ($quality >= 0) { + $this->image->setImageCompressionQuality($quality); } - - return; + $this->image->setImageFormat('webp'); + break; case 'png': if ($quality >= 0) { diff --git a/tests/Image/ImageTest.php b/tests/Image/ImageTest.php index 766ffc9..a84aa07 100644 --- a/tests/Image/ImageTest.php +++ b/tests/Image/ImageTest.php @@ -412,6 +412,46 @@ public function test_crop100x100_webp_quality30(): void \unlink($target); } + public function test_webp_blob_output(): void + { + $image = new Image(\file_get_contents(__DIR__.'/../resources/disk-a/kitten-1.jpg') ?: ''); + + $image->crop(100, 100); + + $blob = $image->output('webp', 75); + + $this->assertIsString($blob); + $this->assertNotEmpty($blob); + $this->assertSame('RIFF', \substr($blob, 0, 4)); + $this->assertSame('WEBP', \substr($blob, 8, 4)); + + $probe = new \Imagick; + $probe->readImageBlob($blob); + $this->assertEquals(100, $probe->getImageWidth()); + $this->assertEquals(100, $probe->getImageHeight()); + $this->assertTrue(in_array($probe->getImageFormat(), ['PAM', 'WEBP'])); + } + + public function test_webp_from_webp_input(): void + { + $image = new Image(\file_get_contents(__DIR__.'/../resources/resize/100x100.webp') ?: ''); + $target = __DIR__.'/roundtrip.webp'; + + $image->crop(50, 50); + + $image->save($target, 'webp', 75); + + $this->assertFileExists($target); + $this->assertNotEmpty(\file_get_contents($target)); + + $probe = new \Imagick($target); + $this->assertEquals(50, $probe->getImageWidth()); + $this->assertEquals(50, $probe->getImageHeight()); + $this->assertTrue(in_array($probe->getImageFormat(), ['PAM', 'WEBP'])); + + \unlink($target); + } + public function test_crop100x100_avif(): void { $image = new Image(\file_get_contents(filename: __DIR__.'/../resources/disk-a/kitten-1.jpg') ?: '');