Update intervention/image.

Changelogs summary:

 - intervention/gif installed in version 3.0.0
   Release notes: https://github.com/Intervention/gif/releases/tag/3.0.0

 - intervention/image updated from 2.7.2 to 3.0.2 major
   See changes: https://github.com/Intervention/image/compare/2.7.2...3.0.2
   Release notes: https://github.com/Intervention/image/releases/tag/3.0.2

No security vulnerability advisories found.
This commit is contained in:
Buster Neece 2023-12-15 07:26:14 -06:00
parent ea399e163b
commit 5a389bb55a
No known key found for this signature in database
10 changed files with 144 additions and 92 deletions

View File

@ -41,7 +41,7 @@
"gettext/php-scanner": "^1.3",
"gettext/translator": "^1.1",
"guzzlehttp/guzzle": "^7.0",
"intervention/image": "^2.6",
"intervention/image": "^3",
"james-heinrich/getid3": "v2.0.0-beta6",
"lbuchs/webauthn": "^2.1",
"league/csv": "^9.6",

107
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "7436fe8e498c7769c9f8c9135316a6c7",
"content-hash": "937d84fd61dbb782e05b56a7d49ee79e",
"packages": [
{
"name": "aws/aws-crt-php",
@ -2645,50 +2645,30 @@
"time": "2023-12-03T20:05:35+00:00"
},
{
"name": "intervention/image",
"version": "2.7.2",
"name": "intervention/gif",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/Intervention/image.git",
"reference": "04be355f8d6734c826045d02a1079ad658322dad"
"url": "https://github.com/Intervention/gif.git",
"reference": "cfececc760862f075a52acf747031bad08c8301b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Intervention/image/zipball/04be355f8d6734c826045d02a1079ad658322dad",
"reference": "04be355f8d6734c826045d02a1079ad658322dad",
"url": "https://api.github.com/repos/Intervention/gif/zipball/cfececc760862f075a52acf747031bad08c8301b",
"reference": "cfececc760862f075a52acf747031bad08c8301b",
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
"guzzlehttp/psr7": "~1.1 || ^2.0",
"php": ">=5.4.0"
"php": "^8.0"
},
"require-dev": {
"mockery/mockery": "~0.9.2",
"phpunit/phpunit": "^4.8 || ^5.7 || ^7.5.15"
},
"suggest": {
"ext-gd": "to use GD library based image processing.",
"ext-imagick": "to use Imagick based image processing.",
"intervention/imagecache": "Caching extension for the Intervention Image library"
"phpstan/phpstan": "^1",
"phpunit/phpunit": "^9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
},
"laravel": {
"providers": [
"Intervention\\Image\\ImageServiceProvider"
],
"aliases": {
"Image": "Intervention\\Image\\Facades\\Image"
}
}
},
"autoload": {
"psr-4": {
"Intervention\\Image\\": "src/Intervention/Image"
"Intervention\\Gif\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@ -2702,19 +2682,74 @@
"homepage": "https://intervention.io/"
}
],
"description": "Image handling and manipulation library with support for Laravel integration",
"homepage": "http://image.intervention.io/",
"description": "Native PHP GIF Encoder/Decoder",
"homepage": "https://github.com/intervention/gif",
"keywords": [
"animation",
"gd",
"gif",
"image"
],
"support": {
"issues": "https://github.com/Intervention/gif/issues",
"source": "https://github.com/Intervention/gif/tree/3.0.0"
},
"time": "2023-11-27T18:54:30+00:00"
},
{
"name": "intervention/image",
"version": "3.0.2",
"source": {
"type": "git",
"url": "https://github.com/Intervention/image.git",
"reference": "ac9734129478be387c1914f1c2856d623341128c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Intervention/image/zipball/ac9734129478be387c1914f1c2856d623341128c",
"reference": "ac9734129478be387c1914f1c2856d623341128c",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"intervention/gif": "^3",
"php": "^8.1"
},
"require-dev": {
"mockery/mockery": "^1.6",
"phpstan/phpstan": "^1",
"phpunit/phpunit": "^9"
},
"type": "library",
"autoload": {
"psr-4": {
"Intervention\\Image\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Oliver Vogel",
"email": "oliver@intervention.io",
"homepage": "https://intervention.io/"
}
],
"description": "PHP image manipulation",
"homepage": "https://image.intervention.io/",
"keywords": [
"gd",
"image",
"imagick",
"laravel",
"resize",
"thumbnail",
"watermark"
],
"support": {
"issues": "https://github.com/Intervention/image/issues",
"source": "https://github.com/Intervention/image/tree/2.7.2"
"source": "https://github.com/Intervention/image/tree/3.0.2"
},
"funding": [
{
@ -2726,7 +2761,7 @@
"type": "github"
}
],
"time": "2022-05-21T17:30:32+00:00"
"time": "2023-12-14T13:17:13+00:00"
},
{
"name": "james-heinrich/getid3",

View File

@ -4,13 +4,18 @@ declare(strict_types=1);
namespace App\Assets;
use Intervention\Image\Interfaces\EncoderInterface;
abstract class AbstractMultiPatternCustomAsset extends AbstractCustomAsset
{
/**
* @return array<string, array{string, EncoderInterface}>
*/
abstract protected function getPatterns(): array;
protected function getPattern(): string
{
return $this->getPatterns()['default'];
return $this->getPatterns()['default'][0];
}
protected function getPathForPattern(string $pattern): string
@ -22,26 +27,26 @@ abstract class AbstractMultiPatternCustomAsset extends AbstractCustomAsset
public function getPath(): string
{
$patterns = $this->getPatterns();
foreach ($patterns as $pattern) {
foreach ($patterns as [$pattern, $encoder]) {
$path = $this->getPathForPattern($pattern);
if (is_file($path)) {
return $path;
}
}
return $this->getPathForPattern($patterns['default']);
return $this->getPathForPattern($patterns['default'][0]);
}
public function delete(): void
{
foreach ($this->getPatterns() as $pattern) {
foreach ($this->getPatterns() as [$pattern, $encoder]) {
@unlink($this->getPathForPattern($pattern));
}
}
public function getUrl(): string
{
foreach ($this->getPatterns() as $pattern) {
foreach ($this->getPatterns() as [$pattern, $encoder]) {
$path = $this->getPathForPattern($pattern);
if (is_file($path)) {

View File

@ -4,17 +4,28 @@ declare(strict_types=1);
namespace App\Assets;
use Intervention\Image\Constraint;
use Intervention\Image\Image;
use Intervention\Image\Encoders\JpegEncoder;
use Intervention\Image\Encoders\PngEncoder;
use Intervention\Image\Encoders\WebpEncoder;
use Intervention\Image\Interfaces\ImageInterface;
final class AlbumArtCustomAsset extends AbstractMultiPatternCustomAsset
{
protected function getPatterns(): array
{
return [
'default' => 'album_art%s.jpg',
'image/png' => 'album_art%s.png',
'image/webp' => 'album_art%s.webp',
'default' => [
'album_art%s.jpg',
new JpegEncoder(90),
],
'image/png' => [
'album_art%s.png',
new PngEncoder(),
],
'image/webp' => [
'album_art%s.webp',
new WebpEncoder(90),
],
];
}
@ -23,23 +34,19 @@ final class AlbumArtCustomAsset extends AbstractMultiPatternCustomAsset
return $this->environment->getAssetUrl() . '/img/generic_song.jpg';
}
public function upload(Image $image): void
public function upload(ImageInterface $image, string $mimeType): void
{
$newImage = clone $image;
$newImage->resize(1500, 1500, function (Constraint $constraint) {
$constraint->upsize();
});
$newImage->resizeDown(1500, 1500);
$this->delete();
$patterns = $this->getPatterns();
$mimeType = $newImage->mime();
$pattern = $patterns[$mimeType] ?? $patterns['default'];
[$pattern, $encoder] = $patterns[$mimeType] ?? $patterns['default'];
$destPath = $this->getPathForPattern($pattern);
$this->ensureDirectoryExists(dirname($destPath));
$newImage->save($destPath, 90);
$newImage->encode($encoder)->save($destPath);
}
}

View File

@ -4,17 +4,28 @@ declare(strict_types=1);
namespace App\Assets;
use Intervention\Image\Constraint;
use Intervention\Image\Image;
use Intervention\Image\Encoders\JpegEncoder;
use Intervention\Image\Encoders\PngEncoder;
use Intervention\Image\Encoders\WebpEncoder;
use Intervention\Image\Interfaces\ImageInterface;
final class BackgroundCustomAsset extends AbstractMultiPatternCustomAsset
{
protected function getPatterns(): array
{
return [
'default' => 'background%s.jpg',
'image/png' => 'background%s.png',
'image/webp' => 'background%s.webp',
'default' => [
'background%s.jpg',
new JpegEncoder(90),
],
'image/png' => [
'background%s.png',
new PngEncoder(),
],
'image/webp' => [
'background%s.webp',
new WebpEncoder(90),
],
];
}
@ -23,23 +34,19 @@ final class BackgroundCustomAsset extends AbstractMultiPatternCustomAsset
return $this->environment->getAssetUrl() . '/img/hexbg.png';
}
public function upload(Image $image): void
public function upload(ImageInterface $image, string $mimeType): void
{
$newImage = clone $image;
$newImage->resize(3264, 2160, function (Constraint $constraint) {
$constraint->upsize();
});
$newImage->resizeDown(3264, 2160);
$this->delete();
$patterns = $this->getPatterns();
$mimeType = $newImage->mime();
$pattern = $patterns[$mimeType] ?? $patterns['default'];
[$pattern, $encoder] = $patterns[$mimeType] ?? $patterns['default'];
$destPath = $this->getPathForPattern($pattern);
$this->ensureDirectoryExists(dirname($destPath));
$newImage->save($destPath, 90);
$newImage->encode($encoder)->save($destPath);
}
}

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace App\Assets;
use Intervention\Image\Image;
use Intervention\Image\Interfaces\ImageInterface;
use Symfony\Component\Filesystem\Filesystem;
final class BrowserIconCustomAsset extends AbstractCustomAsset
@ -38,7 +38,7 @@ final class BrowserIconCustomAsset extends AbstractCustomAsset
return $assetUrl . '/icons/' . $this->environment->getAppEnvironmentEnum()->value . '/original.png';
}
public function upload(Image $image): void
public function upload(ImageInterface $image, string $mimeType): void
{
$this->delete();
@ -47,12 +47,12 @@ final class BrowserIconCustomAsset extends AbstractCustomAsset
$newImage = clone $image;
$newImage->resize(256, 256);
$newImage->save($uploadsDir . '/original.png');
$newImage->toPng()->save($uploadsDir . '/original.png');
foreach (self::ICON_SIZES as $iconSize) {
$newImage = clone $image;
$newImage->resize($iconSize, $iconSize);
$newImage->save($uploadsDir . '/' . $iconSize . '.png');
$newImage->toPng()->save($uploadsDir . '/' . $iconSize . '.png');
}
}

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace App\Assets;
use Intervention\Image\Image;
use Intervention\Image\Interfaces\ImageInterface;
use Psr\Http\Message\UriInterface;
interface CustomAssetInterface
@ -19,7 +19,7 @@ interface CustomAssetInterface
public function getUri(): UriInterface;
public function upload(Image $image): void;
public function upload(ImageInterface $image, string $mimeType): void;
public function delete(): void;
}

View File

@ -11,6 +11,7 @@ use App\Entity\Api\Status;
use App\Http\Response;
use App\Http\ServerRequest;
use App\Media\AlbumArt;
use App\Media\MimeType;
use App\Service\Flow;
use Psr\Http\Message\ResponseInterface;
@ -34,8 +35,10 @@ final class PostCustomAssetAction implements SingleActionInterface
}
$imageContents = $flowResponse->readAndDeleteUploadedFile();
$customAsset->upload(
AlbumArt::getImageManager()->make($imageContents)
AlbumArt::getImageManager()->read($imageContents),
MimeType::getMimeTypeDetector()->detectMimeTypeFromBuffer($imageContents) ?? 'image/jpeg'
);
return $response->withJson(Status::success());

View File

@ -11,6 +11,7 @@ use App\Entity\Api\Status;
use App\Http\Response;
use App\Http\ServerRequest;
use App\Media\AlbumArt;
use App\Media\MimeType;
use App\Service\Flow;
use Psr\Http\Message\ResponseInterface;
@ -38,7 +39,8 @@ final class PostCustomAssetAction implements SingleActionInterface
$imageContents = $flowResponse->readAndDeleteUploadedFile();
$customAsset->upload(
AlbumArt::getImageManager()->make($imageContents)
AlbumArt::getImageManager()->read($imageContents),
MimeType::getMimeTypeDetector()->detectMimeTypeFromBuffer($imageContents) ?? 'image/jpeg'
);
return $response->withJson(Status::success());

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace App\Media;
use Intervention\Image\Constraint;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\ImageManager;
final class AlbumArt
@ -17,28 +17,21 @@ final class AlbumArt
int $height = self::IMAGE_WIDTH,
bool $upsize = false,
): string {
$newArtwork = self::getImageManager()->make($rawArtworkString);
$newArtwork->fit(
$width,
$height,
function (Constraint $constraint) use ($upsize) {
if (!$upsize) {
$constraint->upsize();
}
}
);
$newArtwork = self::getImageManager()->read($rawArtworkString);
$newArtwork->encode('jpg');
if ($upsize) {
$newArtwork->cover($width, $height);
} else {
$newArtwork->coverDown($width, $height);
}
return $newArtwork->getEncoded();
return $newArtwork->toJpeg()->toString();
}
public static function getImageManager(): ImageManager
{
return new ImageManager(
[
'driver' => 'gd',
]
new Driver()
);
}
}