1
0
mirror of https://github.com/Intervention/image.git synced 2025-08-29 00:29:55 +02:00

Implement Image::encodeByExtension()

This commit is contained in:
Oliver Vogel
2023-12-21 16:09:57 +01:00
parent c6d52c39d1
commit 38cdd24c8f
11 changed files with 175 additions and 33 deletions

View File

@@ -24,9 +24,11 @@ class FilePathImageDecoder extends BinaryImageDecoder implements DecoderInterfac
throw new DecoderException('Unable to decode input');
}
// decode image
$image = parent::decode(file_get_contents($input));
// set origin
// set file path on origin
$image->origin()->setFilePath($input);
return $image;
}

View File

@@ -12,18 +12,24 @@ class FilePathImageDecoder extends BinaryImageDecoder implements DecoderInterfac
{
public function decode(mixed $input): ImageInterface|ColorInterface
{
if (! is_string($input)) {
if (!is_string($input)) {
throw new DecoderException('Unable to decode input');
}
try {
if (! @is_file($input)) {
if (!@is_file($input)) {
throw new DecoderException('Unable to decode input');
}
} catch (Exception $e) {
throw new DecoderException('Unable to decode input');
}
return parent::decode(file_get_contents($input));
// decode image
$image = parent::decode(file_get_contents($input));
// set file path on origin
$image->origin()->setFilePath($input);
return $image;
}
}

View File

@@ -2,12 +2,10 @@
namespace Intervention\Image\Encoders;
use Intervention\Gif\Exception\EncoderException;
use Intervention\Image\Interfaces\EncodedImageInterface;
use Intervention\Image\Interfaces\EncoderInterface;
use Intervention\Image\Interfaces\ImageInterface;
class AutoEncoder implements EncoderInterface
class AutoEncoder extends MediaTypeEncoder
{
/**
* {@inheritdoc}
@@ -22,25 +20,4 @@ class AutoEncoder implements EncoderInterface
)
);
}
/**
* Return encoder matching to encode given media (mime) type
*
* @param string $type
* @return EncoderInterface
* @throws EncoderException
*/
protected function encoderByMediaType(string $type): EncoderInterface
{
return match ($type) {
'image/webp' => new WebpEncoder(),
'image/avif' => new AvifEncoder(),
'image/jpeg' => new JpegEncoder(),
'image/bmp' => new BmpEncoder(),
'image/gif' => new GifEncoder(),
'image/png' => new PngEncoder(),
'image/tiff' => new TiffEncoder(),
default => throw new EncoderException('No encoder found for media type (' . $type . ').'),
};
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Intervention\Image\Encoders;
use Intervention\Gif\Exception\EncoderException;
use Intervention\Image\Interfaces\EncodedImageInterface;
use Intervention\Image\Interfaces\EncoderInterface;
use Intervention\Image\Interfaces\ImageInterface;
class FileExtensionEncoder extends AutoEncoder
{
/**
* Create new encoder instance to encode to format of given file extension
*
* @param null|string $extension
* @return void
*/
public function __construct(protected ?string $extension = null)
{
}
/**
* {@inheritdoc}
*
* @see EncoderInterface::encode()
*/
public function encode(ImageInterface $image): EncodedImageInterface
{
return $image->encode(
$this->encoderByFileExtension(
is_null($this->extension) ? $image->origin()->fileExtension() : $this->extension
)
);
}
protected function encoderByFileExtension(string $extension): EncoderInterface
{
return match ($extension) {
'webp' => new WebpEncoder(),
'avif' => new AvifEncoder(),
'jpeg', 'jpg' => new JpegEncoder(),
'bmp' => new BmpEncoder(),
'gif' => new GifEncoder(),
'png' => new PngEncoder(),
'tiff', 'tif' => new TiffEncoder(),
default => throw new EncoderException('No encoder found for file extension (' . $extension . ').'),
};
}
}

View File

@@ -2,10 +2,12 @@
namespace Intervention\Image\Encoders;
use Intervention\Gif\Exception\EncoderException;
use Intervention\Image\Interfaces\EncodedImageInterface;
use Intervention\Image\Interfaces\EncoderInterface;
use Intervention\Image\Interfaces\ImageInterface;
class MediaTypeEncoder extends AutoEncoder
class MediaTypeEncoder implements EncoderInterface
{
/**
* Create new encoder instance to encode given media (mime) type
@@ -24,10 +26,31 @@ class MediaTypeEncoder extends AutoEncoder
*/
public function encode(ImageInterface $image): EncodedImageInterface
{
$type = is_null($this->type) ? $image->origin()->mediaType() : $this->type;
return $image->encode(
$this->encoderByMediaType(
is_null($this->type) ? $image->origin()->mediaType() : $this->type
)
$this->encoderByMediaType($type)
);
}
/**
* Return new encoder by given media (MIME) type
*
* @param string $type
* @return EncoderInterface
* @throws EncoderException
*/
protected function encoderByMediaType(string $type): EncoderInterface
{
return match ($type) {
'image/webp' => new WebpEncoder(),
'image/avif' => new AvifEncoder(),
'image/jpeg' => new JpegEncoder(),
'image/bmp' => new BmpEncoder(),
'image/gif' => new GifEncoder(),
'image/png' => new PngEncoder(),
'image/tiff' => new TiffEncoder(),
default => throw new EncoderException('No encoder found for media type (' . $type . ').'),
};
}
}

View File

@@ -14,6 +14,7 @@ use Intervention\Image\Analyzers\WidthAnalyzer;
use Intervention\Image\Encoders\AutoEncoder;
use Intervention\Image\Encoders\AvifEncoder;
use Intervention\Image\Encoders\BmpEncoder;
use Intervention\Image\Encoders\FileExtensionEncoder;
use Intervention\Image\Encoders\GifEncoder;
use Intervention\Image\Encoders\JpegEncoder;
use Intervention\Image\Encoders\MediaTypeEncoder;
@@ -755,6 +756,16 @@ final class Image implements ImageInterface, Countable
return $this->encode(new MediaTypeEncoder($type));
}
/**
* {@inheritdoc}
*
* @see ImageInterface::encodeByExtension()
*/
public function encodeByExtension(?string $extension = null): EncodedImageInterface
{
return $this->encode(new FileExtensionEncoder($extension));
}
/**
* {@inheritdoc}
*

View File

@@ -566,6 +566,16 @@ interface ImageInterface extends IteratorAggregate, Countable
*/
public function encodeByMediaType(?string $type = null): EncodedImageInterface;
/**
* Encode the image into the format represented by the given extension. If no
* extension is given the image will be encoded to the format of the
* originally read image.
*
* @param null|string $extension
* @return EncodedImageInterface
*/
public function encodeByExtension(?string $extension = null): EncodedImageInterface;
/**
* Encode image to JPEG format
*

View File

@@ -8,20 +8,53 @@ class Origin
* Create new origin instance
*
* @param string $mediaType
* @param null|string $filePath
* @return void
*/
public function __construct(
protected string $mediaType = 'application/octet-stream'
protected string $mediaType = 'application/octet-stream',
protected ?string $filePath = null
) {
}
/**
* Return media type of origin
*
* @return string
*/
public function mediaType(): string
{
return $this->mediaType;
}
/**
* Alias of self::mediaType()
*/
public function mimetype(): string
{
return $this->mediaType();
}
/**
* Set file path for origin
*
* @param string $path
* @return Origin
*/
public function setFilePath(string $path): self
{
$this->filePath = $path;
return $this;
}
/**
* Return file extension if origin was created from file path
*
* @return null|string
*/
public function fileExtension(): ?string
{
return empty($this->filePath) ? null : pathinfo($this->filePath, PATHINFO_EXTENSION);
}
}

View File

@@ -133,6 +133,17 @@ class ImageTest extends TestCase
$this->assertMediaType('image/png', (string) $result);
}
public function testEncodeByExtension(): void
{
$result = $this->readTestImage('blue.gif')->encodeByExtension();
$this->assertInstanceOf(EncodedImage::class, $result);
$this->assertMediaType('image/gif', (string) $result);
$result = $this->readTestImage('blue.gif')->encodeByExtension('png');
$this->assertInstanceOf(EncodedImage::class, $result);
$this->assertMediaType('image/png', (string) $result);
}
public function testWidthHeightSize(): void
{
$this->assertEquals(3, $this->image->width());

View File

@@ -132,6 +132,17 @@ class ImageTest extends TestCase
$this->assertMediaType('image/png', (string) $result);
}
public function testEncodeByExtension(): void
{
$result = $this->readTestImage('blue.gif')->encodeByExtension();
$this->assertInstanceOf(EncodedImage::class, $result);
$this->assertMediaType('image/gif', (string) $result);
$result = $this->readTestImage('blue.gif')->encodeByExtension('png');
$this->assertInstanceOf(EncodedImage::class, $result);
$this->assertMediaType('image/png', (string) $result);
}
public function testWidthHeightSize(): void
{
$this->assertEquals(20, $this->image->width());

View File

@@ -14,4 +14,13 @@ class OriginTest extends TestCase
$origin = new Origin('image/gif');
$this->assertEquals('image/gif', $origin->mediaType());
}
public function testFileExtension(): void
{
$origin = new Origin('image/jpeg', __DIR__ . '/tests/images/example.jpg');
$this->assertEquals('jpg', $origin->fileExtension());
$origin = new Origin('image/jpeg');
$this->assertEquals('', $origin->fileExtension());
}
}