ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
CropSquare.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
33
39{
41
42 public const ID = 'crop_square';
43 public const QUALITY = 30;
44
45 public function getId(): string
46 {
47 return self::ID;
48 }
49
50 public function canHandleDefinition(FlavourDefinition $definition): bool
51 {
52 return $definition instanceof CropToSquare;
53 }
54
55 public function dependsOnEngine(): ?string
56 {
57 return GDEngine::class;
58 }
59
60 public function processStream(
61 FileInformation $information,
62 FileStream $stream,
63 FlavourDefinition $for_definition
64 ): \Generator {
65 if (!$for_definition instanceof CropToSquare) {
66 throw new \InvalidArgumentException('Invalid definition');
67 }
68 $image = $this->from($stream);
69 if (!is_resource($image) && !$image instanceof \GdImage) {
70 return;
71 }
72
73 $stream_path = $stream->getMetadata()['uri'] ?? '';
74 $must_flip = $this->maybeRotate($stream_path, $image);
75
76 if ($stream_path === 'php://memory') {
77 [$width, $height] = getimagesizefromstring((string) $stream);
78 } else {
79 [$width, $height] = getimagesize($stream_path);
80 }
81
82 if ($must_flip) {
83 $tmp = $width;
84 $width = $height;
85 $height = $tmp;
86 }
87
88 if ($width > $height) {
89 $y = 0;
90 $x = (int) (($width - $height) / 2);
91 $smallest_side = (int) $height;
92 } else {
93 $x = 0;
94 $y = (int) (($height - $width) / 2);
95 $smallest_side = (int) $width;
96 }
97
98 $size = (int) $for_definition->getMaxSize();
99
100 $thumb = imagecreatetruecolor($size, $size);
101
102 imagecopyresampled(
103 $thumb,
104 $image,
105 0,
106 0,
107 $x,
108 $y,
109 $size,
110 $size,
111 $smallest_side,
112 $smallest_side
113 );
114
115 imagedestroy($image);
116
117 $stream = $this->to($thumb, $for_definition->getQuality());
118
119 yield new Result(
120 $for_definition,
121 $stream,
122 0,
123 $for_definition->persist()
124 );
125 }
126
127 protected function maybeRotate(string $stream_path, \GdImage &$image): bool
128 {
129 // if PHP exif is installed, this is quite easy
130 $exif = new ExifEngine();
131 if ($exif->isRunning() && ($exif_data = $exif->read($stream_path)) !== []) {
132 switch ($exif_data['Orientation'] ?? null) {
133 case 8:
134 $image = imagerotate($image, 90, 0);
135 return true;
136 case 3:
137 $image = imagerotate($image, 180, 0);
138 return false;
139 case 6:
140 $image = imagerotate($image, -90, 0);
141 return true;
142 default:
143 return false;
144 }
145 }
146 // otherwise we can use Imagick (if installed)
147 $imagick = new ImagickEngine();
148 if ($imagick->isRunning()) {
149 $imagick = new \Imagick($stream_path);
150 $image_orientation = $imagick->getImageOrientation();
151 switch ($image_orientation) {
152 case \Imagick::ORIENTATION_RIGHTTOP:
153 $imagick->rotateImage('none', 90);
154 $imagick->setImageOrientation(\Imagick::ORIENTATION_TOPLEFT);
155 $image = $this->from(Streams::ofString($imagick->getImageBlob()));
156 return true;
157 case \Imagick::ORIENTATION_BOTTOMRIGHT:
158 $imagick->rotateImage('none', 180);
159 $imagick->setImageOrientation(\Imagick::ORIENTATION_TOPLEFT);
160 $image = $this->from(Streams::ofString($imagick->getImageBlob()));
161 return false;
162 case \Imagick::ORIENTATION_LEFTBOTTOM:
163 $imagick->rotateImage('none', -90);
164 $imagick->setImageOrientation(\Imagick::ORIENTATION_TOPLEFT);
165 $image = $this->from(Streams::ofString($imagick->getImageBlob()));
166 return true;
167 default:
168 return false;
169 }
170 }
171
172 // we did not find any way to rotate the image
173 return false;
174 }
175}
Stream factory which enables the user to create streams without the knowledge of the concrete class.
Definition: Streams.php:32
static ofString(string $string)
Creates a new stream with an initial value.
Definition: Streams.php:41
canHandleDefinition(FlavourDefinition $definition)
Check if a corresponding configuration can be processed by this Machine.
Definition: CropSquare.php:50
dependsOnEngine()
Return the class name of the Engine that is required for this Machine to work.
Definition: CropSquare.php:55
processStream(FileInformation $information, FileStream $stream, FlavourDefinition $for_definition)
Definition: CropSquare.php:60
The base interface for all filesystem streams.
Definition: FileStream.php:32
to(\GdImage $image, ?int $quality=null)
Currently this is the only way to make a FileStream from a GD image resource.
if(!file_exists('../ilias.ini.php'))