Skip to content

Commit

Permalink
Switch EncodedImage::class to temporary stream resource
Browse files Browse the repository at this point in the history
  • Loading branch information
olivervogel authored Oct 6, 2024
1 parent e244bc9 commit e77a333
Show file tree
Hide file tree
Showing 44 changed files with 265 additions and 242 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"require": {
"php": "^8.1",
"ext-mbstring": "*",
"intervention/gif": "^4.1"
"intervention/gif": "^4.2"
},
"require-dev": {
"phpunit/phpunit": "^10.0",
Expand Down
20 changes: 12 additions & 8 deletions src/Drivers/AbstractEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@

namespace Intervention\Image\Drivers;

use Intervention\Image\EncodedImage;
use Intervention\Image\Exceptions\RuntimeException;
use Intervention\Image\Interfaces\EncodedImageInterface;
use Intervention\Image\Interfaces\EncoderInterface;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Traits\CanBuildFilePointer;

abstract class AbstractEncoder implements EncoderInterface
{
use CanBuildFilePointer;

public const DEFAULT_QUALITY = 75;

/**
Expand All @@ -23,18 +28,17 @@ public function encode(ImageInterface $image): EncodedImageInterface
}

/**
* Get return value of callback through output buffer
* Build new file pointer, run callback with it and return result as encoded image
*
* @param callable $callback
* @return string
* @throws RuntimeException
* @return EncodedImage
*/
protected function buffered(callable $callback): string
protected function createEncodedImage(callable $callback): EncodedImage
{
ob_start();
$callback();
$buffer = ob_get_contents();
ob_end_clean();
$pointer = $this->buildFilePointer();
$callback($pointer);

return $buffer;
return new EncodedImage($pointer);
}
}
33 changes: 19 additions & 14 deletions src/Drivers/Gd/Decoders/NativeObjectDecoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Intervention\Image\Drivers\Gd\Decoders;

use Exception;
use GdImage;
use Intervention\Gif\Decoder as GifDecoder;
use Intervention\Gif\Splitter as GifSplitter;
Expand Down Expand Up @@ -76,23 +77,27 @@ protected function decodeGif(mixed $input): ImageInterface
return $image;
}

// create empty core
$core = new Core();
try {
// create empty core
$core = new Core();

$gif = GifDecoder::decode($input);
$splitter = GifSplitter::create($gif)->split();
$delays = $splitter->getDelays();
$gif = GifDecoder::decode($input);
$splitter = GifSplitter::create($gif)->split();
$delays = $splitter->getDelays();

// set loops on core
if ($loops = $gif->getMainApplicationExtension()?->getLoops()) {
$core->setLoops($loops);
}
// set loops on core
if ($loops = $gif->getMainApplicationExtension()?->getLoops()) {
$core->setLoops($loops);
}

// add GDImage instances to core
foreach ($splitter->coalesceToResources() as $key => $native) {
$core->push(
new Frame($native, $delays[$key] / 100)
);
// add GDImage instances to core
foreach ($splitter->coalesceToResources() as $key => $native) {
$core->push(
new Frame($native, $delays[$key] / 100)
);
}
} catch (Exception $e) {
throw new DecoderException($e->getMessage(), $e->getCode(), $e);
}

// create (possibly) animated image
Expand Down
7 changes: 2 additions & 5 deletions src/Drivers/Gd/Encoders/AvifEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,8 @@ class AvifEncoder extends GenericAvifEncoder implements SpecializedInterface
*/
public function encode(ImageInterface $image): EncodedImage
{
$gd = $image->core()->native();
$data = $this->buffered(function () use ($gd) {
imageavif($gd, null, $this->quality);
return $this->createEncodedImage(function ($pointer) use ($image) {
imageavif($image->core()->native(), $pointer, $this->quality);
});

return new EncodedImage($data, 'image/avif');
}
}
6 changes: 2 additions & 4 deletions src/Drivers/Gd/Encoders/BmpEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ class BmpEncoder extends GenericBmpEncoder implements SpecializedInterface
*/
public function encode(ImageInterface $image): EncodedImage
{
$data = $this->buffered(function () use ($image) {
imagebmp($image->core()->native(), null, false);
return $this->createEncodedImage(function ($pointer) use ($image) {
imagebmp($image->core()->native(), $pointer, false);
});

return new EncodedImage($data, 'image/bmp');
}
}
35 changes: 17 additions & 18 deletions src/Drivers/Gd/Encoders/GifEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,38 +28,37 @@ public function encode(ImageInterface $image): EncodedImage
}

$gd = Cloner::clone($image->core()->native());
$data = $this->buffered(function () use ($gd) {

return $this->createEncodedImage(function ($pointer) use ($gd) {
imageinterlace($gd, $this->interlaced);
imagegif($gd);
imagegif($gd, $pointer);
});

return new EncodedImage($data, 'image/gif');
}

/**
* @throws RuntimeException
*/
protected function encodeAnimated(ImageInterface $image): EncodedImage
{
$builder = GifBuilder::canvas(
$image->width(),
$image->height()
);

foreach ($image as $frame) {
$builder->addFrame(
source: (string) $this->encode($frame->toImage($image->driver())),
delay: $frame->delay(),
interlaced: $this->interlaced
try {
$builder = GifBuilder::canvas(
$image->width(),
$image->height()
);
}

try {
foreach ($image as $frame) {
$builder->addFrame(
source: $this->encode($frame->toImage($image->driver()))->toFilePointer(),
delay: $frame->delay(),
interlaced: $this->interlaced
);
}

$builder->setLoops($image->loops());

return new EncodedImage($builder->encode());
} catch (Exception $e) {
throw new EncoderException($e->getMessage(), $e->getCode(), $e);
}

return new EncodedImage($builder->encode(), 'image/gif');
}
}
6 changes: 2 additions & 4 deletions src/Drivers/Gd/Encoders/JpegEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,9 @@ public function encode(ImageInterface $image): EncodedImage
background: $blendingColor
);

$data = $this->buffered(function () use ($output) {
return $this->createEncodedImage(function ($pointer) use ($output) {
imageinterlace($output, $this->progressive);
imagejpeg($output, null, $this->quality);
imagejpeg($output, $pointer, $this->quality);
});

return new EncodedImage($data, 'image/jpeg');
}
}
7 changes: 2 additions & 5 deletions src/Drivers/Gd/Encoders/PngEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,10 @@ public function encode(ImageInterface $image): EncodedImage
{
$output = $this->prepareOutput($image);

// encode
$data = $this->buffered(function () use ($output) {
return $this->createEncodedImage(function ($pointer) use ($output) {
imageinterlace($output, $this->interlaced);
imagepng($output, null, -1);
imagepng($output, $pointer, -1);
});

return new EncodedImage($data, 'image/png');
}

/**
Expand Down
7 changes: 3 additions & 4 deletions src/Drivers/Gd/Encoders/WebpEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ class WebpEncoder extends GenericWebpEncoder implements SpecializedInterface
public function encode(ImageInterface $image): EncodedImage
{
$quality = $this->quality === 100 ? IMG_WEBP_LOSSLESS : $this->quality;
$data = $this->buffered(function () use ($image, $quality) {
imagewebp($image->core()->native(), null, $quality);
});

return new EncodedImage($data, 'image/webp');
return $this->createEncodedImage(function ($pointer) use ($image, $quality) {
imagewebp($image->core()->native(), $pointer, $quality);
});
}
}
5 changes: 3 additions & 2 deletions src/Drivers/Imagick/Encoders/AvifEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
use Imagick;
use Intervention\Image\EncodedImage;
use Intervention\Image\Encoders\AvifEncoder as GenericAvifEncoder;
use Intervention\Image\Interfaces\EncodedImageInterface;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\SpecializedInterface;

class AvifEncoder extends GenericAvifEncoder implements SpecializedInterface
{
public function encode(ImageInterface $image): EncodedImage
public function encode(ImageInterface $image): EncodedImageInterface
{
$format = 'AVIF';
$compression = Imagick::COMPRESSION_ZIP;
Expand All @@ -25,6 +26,6 @@ public function encode(ImageInterface $image): EncodedImage
$imagick->setCompressionQuality($this->quality);
$imagick->setImageCompressionQuality($this->quality);

return new EncodedImage($imagick->getImagesBlob(), 'image/avif');
return new EncodedImage($imagick->getImagesBlob());
}
}
5 changes: 3 additions & 2 deletions src/Drivers/Imagick/Encoders/BmpEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
use Imagick;
use Intervention\Image\EncodedImage;
use Intervention\Image\Encoders\BmpEncoder as GenericBmpEncoder;
use Intervention\Image\Interfaces\EncodedImageInterface;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\SpecializedInterface;

class BmpEncoder extends GenericBmpEncoder implements SpecializedInterface
{
public function encode(ImageInterface $image): EncodedImage
public function encode(ImageInterface $image): EncodedImageInterface
{
$format = 'BMP';
$compression = Imagick::COMPRESSION_NO;
Expand All @@ -23,6 +24,6 @@ public function encode(ImageInterface $image): EncodedImage
$imagick->setCompression($compression);
$imagick->setImageCompression($compression);

return new EncodedImage($imagick->getImagesBlob(), 'image/bmp');
return new EncodedImage($imagick->getImagesBlob());
}
}
5 changes: 3 additions & 2 deletions src/Drivers/Imagick/Encoders/GifEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
use Imagick;
use Intervention\Image\EncodedImage;
use Intervention\Image\Encoders\GifEncoder as GenericGifEncoder;
use Intervention\Image\Interfaces\EncodedImageInterface;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\SpecializedInterface;

class GifEncoder extends GenericGifEncoder implements SpecializedInterface
{
public function encode(ImageInterface $image): EncodedImage
public function encode(ImageInterface $image): EncodedImageInterface
{
$format = 'GIF';
$compression = Imagick::COMPRESSION_LZW;
Expand All @@ -28,6 +29,6 @@ public function encode(ImageInterface $image): EncodedImage
$imagick->setInterlaceScheme(Imagick::INTERLACE_LINE);
}

return new EncodedImage($imagick->getImagesBlob(), 'image/gif');
return new EncodedImage($imagick->getImagesBlob());
}
}
5 changes: 2 additions & 3 deletions src/Drivers/Imagick/Encoders/HeicEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

use Intervention\Image\EncodedImage;
use Intervention\Image\Encoders\HeicEncoder as GenericHeicEncoder;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\EncodedImageInterface;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\SpecializedInterface;

class HeicEncoder extends GenericHeicEncoder implements SpecializedInterface
Expand All @@ -17,12 +17,11 @@ public function encode(ImageInterface $image): EncodedImageInterface
$format = 'HEIC';

$imagick = $image->core()->native();

$imagick->setFormat($format);
$imagick->setImageFormat($format);
$imagick->setCompressionQuality($this->quality);
$imagick->setImageCompressionQuality($this->quality);

return new EncodedImage($imagick->getImagesBlob(), 'image/heic');
return new EncodedImage($imagick->getImagesBlob());
}
}
2 changes: 1 addition & 1 deletion src/Drivers/Imagick/Encoders/Jpeg2000Encoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ public function encode(ImageInterface $image): EncodedImageInterface
$imagick->setCompressionQuality($this->quality);
$imagick->setImageCompressionQuality($this->quality);

return new EncodedImage($imagick->getImagesBlob(), 'image/jp2');
return new EncodedImage($imagick->getImagesBlob());
}
}
5 changes: 3 additions & 2 deletions src/Drivers/Imagick/Encoders/JpegEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
use Imagick;
use Intervention\Image\EncodedImage;
use Intervention\Image\Encoders\JpegEncoder as GenericJpegEncoder;
use Intervention\Image\Interfaces\EncodedImageInterface;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\SpecializedInterface;

class JpegEncoder extends GenericJpegEncoder implements SpecializedInterface
{
public function encode(ImageInterface $image): EncodedImage
public function encode(ImageInterface $image): EncodedImageInterface
{
$format = 'JPEG';
$compression = Imagick::COMPRESSION_JPEG;
Expand Down Expand Up @@ -44,6 +45,6 @@ public function encode(ImageInterface $image): EncodedImage
$imagick->setInterlaceScheme(Imagick::INTERLACE_PLANE);
}

return new EncodedImage($imagick->getImagesBlob(), 'image/jpeg');
return new EncodedImage($imagick->getImagesBlob());
}
}
Loading

0 comments on commit e77a333

Please sign in to comment.