mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-07-31 15:24:31 +03:00
Images: Started refactor of image service
To break it up. Also added better memory handling to other parts of the app.
This commit is contained in:
95
app/Uploads/ImageResizer.php
Normal file
95
app/Uploads/ImageResizer.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace BookStack\Uploads;
|
||||
|
||||
use BookStack\Exceptions\ImageUploadException;
|
||||
use GuzzleHttp\Psr7\Utils;
|
||||
use Intervention\Image\Exception\NotSupportedException;
|
||||
use Intervention\Image\Image as InterventionImage;
|
||||
use Intervention\Image\ImageManager;
|
||||
|
||||
class ImageResizer
|
||||
{
|
||||
public function __construct(
|
||||
protected ImageManager $intervention
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize the image of given data to the specified size, and return the new image data.
|
||||
*
|
||||
* @throws ImageUploadException
|
||||
*/
|
||||
protected function resizeImageData(string $imageData, ?int $width, ?int $height, bool $keepRatio): string
|
||||
{
|
||||
try {
|
||||
$thumb = $this->intervention->make($imageData);
|
||||
} catch (NotSupportedException $e) {
|
||||
throw new ImageUploadException(trans('errors.cannot_create_thumbs'));
|
||||
}
|
||||
|
||||
$this->orientImageToOriginalExif($thumb, $imageData);
|
||||
|
||||
if ($keepRatio) {
|
||||
$thumb->resize($width, $height, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
});
|
||||
} else {
|
||||
$thumb->fit($width, $height);
|
||||
}
|
||||
|
||||
$thumbData = (string) $thumb->encode();
|
||||
|
||||
// Use original image data if we're keeping the ratio
|
||||
// and the resizing does not save any space.
|
||||
if ($keepRatio && strlen($thumbData) > strlen($imageData)) {
|
||||
return $imageData;
|
||||
}
|
||||
|
||||
return $thumbData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Orientate the given intervention image based upon the given original image data.
|
||||
* Intervention does have an `orientate` method but the exif data it needs is lost before it
|
||||
* can be used (At least when created using binary string data) so we need to do some
|
||||
* implementation on our side to use the original image data.
|
||||
* Bulk of logic taken from: https://github.com/Intervention/image/blob/b734a4988b2148e7d10364b0609978a88d277536/src/Intervention/Image/Commands/OrientateCommand.php
|
||||
* Copyright (c) Oliver Vogel, MIT License.
|
||||
*/
|
||||
protected function orientImageToOriginalExif(InterventionImage $image, string $originalData): void
|
||||
{
|
||||
if (!extension_loaded('exif')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$stream = Utils::streamFor($originalData)->detach();
|
||||
$exif = @exif_read_data($stream);
|
||||
$orientation = $exif ? ($exif['Orientation'] ?? null) : null;
|
||||
|
||||
switch ($orientation) {
|
||||
case 2:
|
||||
$image->flip();
|
||||
break;
|
||||
case 3:
|
||||
$image->rotate(180);
|
||||
break;
|
||||
case 4:
|
||||
$image->rotate(180)->flip();
|
||||
break;
|
||||
case 5:
|
||||
$image->rotate(270)->flip();
|
||||
break;
|
||||
case 6:
|
||||
$image->rotate(270);
|
||||
break;
|
||||
case 7:
|
||||
$image->rotate(90)->flip();
|
||||
break;
|
||||
case 8:
|
||||
$image->rotate(90);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user