3 namespace BookStack\Uploads;
5 use BookStack\Exceptions\ImageUploadException;
6 use GuzzleHttp\Psr7\Utils;
7 use Intervention\Image\Exception\NotSupportedException;
8 use Intervention\Image\Image as InterventionImage;
9 use Intervention\Image\ImageManager;
13 public function __construct(
14 protected ImageManager $intervention
19 * Resize the image of given data to the specified size, and return the new image data.
21 * @throws ImageUploadException
23 protected function resizeImageData(string $imageData, ?int $width, ?int $height, bool $keepRatio): string
26 $thumb = $this->intervention->make($imageData);
27 } catch (NotSupportedException $e) {
28 throw new ImageUploadException(trans('errors.cannot_create_thumbs'));
31 $this->orientImageToOriginalExif($thumb, $imageData);
34 $thumb->resize($width, $height, function ($constraint) {
35 $constraint->aspectRatio();
36 $constraint->upsize();
39 $thumb->fit($width, $height);
42 $thumbData = (string) $thumb->encode();
44 // Use original image data if we're keeping the ratio
45 // and the resizing does not save any space.
46 if ($keepRatio && strlen($thumbData) > strlen($imageData)) {
54 * Orientate the given intervention image based upon the given original image data.
55 * Intervention does have an `orientate` method but the exif data it needs is lost before it
56 * can be used (At least when created using binary string data) so we need to do some
57 * implementation on our side to use the original image data.
58 * Bulk of logic taken from: https://github.com/Intervention/image/blob/b734a4988b2148e7d10364b0609978a88d277536/src/Intervention/Image/Commands/OrientateCommand.php
59 * Copyright (c) Oliver Vogel, MIT License.
61 protected function orientImageToOriginalExif(InterventionImage $image, string $originalData): void
63 if (!extension_loaded('exif')) {
67 $stream = Utils::streamFor($originalData)->detach();
68 $exif = @exif_read_data($stream);
69 $orientation = $exif ? ($exif['Orientation'] ?? null) : null;
71 switch ($orientation) {
79 $image->rotate(180)->flip();
82 $image->rotate(270)->flip();
88 $image->rotate(90)->flip();