diff --git a/docs/docs/alterations/base64.md b/docs/docs/alterations/base64.md new file mode 100644 index 0000000..9738328 --- /dev/null +++ b/docs/docs/alterations/base64.md @@ -0,0 +1,29 @@ +--- +sidebar_position: 1 +_modified_: true +--- +# `base64()` + +```php +->base64([SergiX44\ImageZen\Format $format = SergiX44\ImageZen\Format::PNG], [int $quality = 90]): string +``` +Return the image as base64 encoded string. + +## Parameters + +- `SergiX44\ImageZen\Format $format`: The image format, default is PNG. +- `int $quality`: The image quality, default is 90, if supported by the format. + + +## Returns + +`string`: The image as base64 string. + +## Example + +```php +use SergiX44\ImageZen\Image; + +$base64 = Image::make('path/to/image.jpg')->base64(\SergiX44\ImageZen\Format::JPG); // data:image/jpg;base64,... + +``` diff --git a/docs/docs/alterations/greyscale.md b/docs/docs/alterations/greyscale.md index 2b46884..cb077a2 100644 --- a/docs/docs/alterations/greyscale.md +++ b/docs/docs/alterations/greyscale.md @@ -1,5 +1,5 @@ --- -sidebar_position: 26 +sidebar_position: 27 _modified_: false --- # `greyscale()` diff --git a/docs/docs/alterations/invert.md b/docs/docs/alterations/invert.md index d0707f9..620a998 100644 --- a/docs/docs/alterations/invert.md +++ b/docs/docs/alterations/invert.md @@ -1,5 +1,5 @@ --- -sidebar_position: 30 +sidebar_position: 31 _modified_: false --- # `invert()` diff --git a/docs/docs/alterations/save.md b/docs/docs/alterations/save.md index 842eeef..b27a0a4 100644 --- a/docs/docs/alterations/save.md +++ b/docs/docs/alterations/save.md @@ -31,6 +31,6 @@ $success = Image::make('path/to/image.jpg') ->save('path/to/image.png', \SergiX44\ImageZen\Format::PNG); // save the image as PNG $success = Image::make('path/to/image.jpg') - ->save('path/to/image.png', \SergiX44\ImageZen\Format::\SergiX44\ImageZen\JPG, 50); // save the image as JPG with a quality of 50 + ->save('path/to/image.png', \SergiX44\ImageZen\Format::JPG, 50); // save the image as JPG with a quality of 50 ``` diff --git a/generator.php b/generator.php index 6debd2c..013cc68 100644 --- a/generator.php +++ b/generator.php @@ -17,6 +17,7 @@ $availableMethods = [ $imageReflection->getMethod('make'), + $imageReflection->getMethod('base64'), $imageReflection->getMethod('canvas'), $imageReflection->getMethod('register'), $imageReflection->getMethod('width'), diff --git a/src/Alterations/Fill.php b/src/Alterations/Fill.php index 6815667..9f46f3d 100644 --- a/src/Alterations/Fill.php +++ b/src/Alterations/Fill.php @@ -106,7 +106,7 @@ public function applyWithImagick(Image $image): null // replace image core $this->replaceCore($image, $canvas); - // flood fill with color + // flood fill with color } elseif ($this->color !== null) { // create canvas with filling $canvas = new \Imagick(); diff --git a/src/Drivers/Driver.php b/src/Drivers/Driver.php index bbda894..d772f66 100644 --- a/src/Drivers/Driver.php +++ b/src/Drivers/Driver.php @@ -29,4 +29,6 @@ public function clone(Image $image): GdImage|Imagick; public function clear(?Image $image = null, ?object $raw = null): void; public function apply(Alteration $alteration, Image $image): mixed; + + public function getData(): array; } diff --git a/src/Drivers/Gd/Gd.php b/src/Drivers/Gd/Gd.php index f661d72..69f793d 100644 --- a/src/Drivers/Gd/Gd.php +++ b/src/Drivers/Gd/Gd.php @@ -17,6 +17,8 @@ class Gd implements Driver { + private $data = []; + public function isAvailable(): bool { return extension_loaded('gd') && function_exists('gd_info'); @@ -55,9 +57,12 @@ public function parseColor(Color $color): GdColor */ public function loadImageFrom(string $path): GdImage { - if (file_exists($path)) { - $resource = imagecreatefromstring(file_get_contents($path)); + if (file_exists($path) || filter_var($path, FILTER_VALIDATE_URL) !== false) { + $data = file_get_contents($path); + $this->data = getimagesizefromstring($data); + $resource = imagecreatefromstring($data); } else { + $this->data = getimagesizefromstring($path); $resource = imagecreatefromstring($path); } @@ -138,4 +143,9 @@ private function toTrueColor(GdImage $resource): GdImage return $canvas; } + + public function getData(): array + { + return $this->data; + } } diff --git a/src/Drivers/Imagick/Imagick.php b/src/Drivers/Imagick/Imagick.php index 4ca6d87..3fdee2e 100644 --- a/src/Drivers/Imagick/Imagick.php +++ b/src/Drivers/Imagick/Imagick.php @@ -261,4 +261,9 @@ public function clone(Image $image): ImagickBackend { return clone $image->getCore(); } + + public function getData(): array + { + return []; + } } diff --git a/src/Format.php b/src/Format.php index f70509f..e0d2ac6 100644 --- a/src/Format.php +++ b/src/Format.php @@ -26,4 +26,18 @@ public function name(): string self::AVIF => 'avif', }; } + + public function mime() + { + return match ($this) { + self::PNG => 'image/png', + self::JPG => 'image/jpeg', + self::WEBP => 'image/webp', + self::GIF => 'image/gif', + self::BMP => 'image/bmp', + self::TIFF => 'image/tiff', + self::HEIC => 'image/heic', + self::AVIF => 'image/avif', + }; + } } diff --git a/src/Getters/GetMime.php b/src/Getters/GetMime.php index a75ab69..b24b3d6 100644 --- a/src/Getters/GetMime.php +++ b/src/Getters/GetMime.php @@ -2,7 +2,6 @@ namespace SergiX44\ImageZen\Getters; -use RuntimeException; use SergiX44\ImageZen\Alteration; use SergiX44\ImageZen\Drivers\Gd\GdAlteration; use SergiX44\ImageZen\Drivers\Imagick\ImagickAlteration; @@ -12,26 +11,15 @@ class GetMime extends Alteration implements GdAlteration, ImagickAlteration { public static string $id = 'mime'; - protected function getMimeType(Image $image): string - { - $finfo = finfo_open(FILEINFO_MIME_TYPE); - $mime = finfo_buffer($finfo, $image->stream()->getContents()); - finfo_close($finfo); - - if ($mime === false) { - throw new RuntimeException('Unable to get mime type'); - } - - return $mime; - } - public function applyWithGd(Image $image): string { - return $this->getMimeType($image); + $imageInfo = $image->getDriver()->getData(); + + return $imageInfo['mime']; } public function applyWithImagick(Image $image): string { - return $this->getMimeType($image); + return str_ireplace('/x-', '/', $image->getCore()->getImageMimeType()); } } diff --git a/src/Image.php b/src/Image.php index f2bdee3..e5ea030 100644 --- a/src/Image.php +++ b/src/Image.php @@ -220,6 +220,18 @@ public function stream(Format $format = Format::PNG, int $quality = 90): StreamI return $this->driver->getStream($this, $format, $quality); } + /** + * Return the image as base64 string. + * + * @param Format $format The image format, default is PNG. + * @param int $quality The image quality, default is 90, if supported by the format. + * @return string The image as base64 string. + */ + public function base64(Format $format = Format::PNG, int $quality = 90): string + { + return 'data:'.$format->mime().';base64,'.base64_encode($this->stream($format, $quality)->getContents()); + } + /** * Get the image path if it was loaded from a file. * @@ -242,7 +254,7 @@ public function response(Format $format = Format::PNG, int $quality = 90): Respo return new Response( status: 200, headers: [ - 'Content-Type' => $this->mime(), + 'Content-Type' => $format->mime(), ], body: $this->stream($format, $quality), ); diff --git a/tests/DriverTest.php b/tests/DriverTest.php index 1bdd219..c1a1170 100644 --- a/tests/DriverTest.php +++ b/tests/DriverTest.php @@ -620,3 +620,15 @@ function prepare($instance, string $name, Backend $driver, string $ext = 'png'): ->imageSimilarTo($expected); unlink($out); })->with('drivers', 'fruit'); + +it('can output an image as base64 with png', function ($driver, $file) { + prepare($this, '_', $driver); + $b64 = Image::make($file, $driver)->base64(); + expect($b64)->toStartWith('data:image/png;base64,iVBORw0KGgo'); +})->with('drivers', 'tile'); + +it('can output an image as base64 with jpg', function ($driver, $file) { + prepare($this, '_', $driver); + $b64 = Image::make($file, $driver)->base64(\SergiX44\ImageZen\Format::JPG); + expect($b64)->toStartWith('data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ'); +})->with('drivers', 'tile');