ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
ExtractPages.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
35
41{
42 use ImageSizeCalculator;
43
44 public const ID = 'extract_pages';
45 private bool $high_quality = false;
46
47 public function getId(): string
48 {
49 return self::ID;
50 }
51
52 public function dependsOnEngine(): ?string
53 {
54 return ImagickEngineWithOptionalFFMpeg::class;
55 }
56
57 public function canHandleDefinition(FlavourDefinition $definition): bool
58 {
59 return $definition instanceof PagesToExtract;
60 }
61
62 public function processStream(
63 FileInformation $information,
64 FileStream $stream,
65 FlavourDefinition $for_definition
66 ): \Generator {
67 if (!$for_definition instanceof PagesToExtract) {
68 throw new \InvalidArgumentException('Invalid definition');
69 }
70
71 if (!class_exists(\Imagick::class)) {
72 return;
73 }
74
75 // Create target image
76 $img = new \Imagick();
77
78 // Quality Settings
79 $this->high_quality = $for_definition->useMaxQuality();
80 if ($this->high_quality) {
81 $quality = 100;
82 $img->setResolution(300, 300); // way better previews for PDFs. Must be set before reading the file
83 } else {
84 $quality = $for_definition->getQuality();
85 }
86
87 $extractor = new General();
88
89 $mime_type = $information->getMimeType();
90 switch (true) {
91 case ($mime_type === 'image/svg+xml' || $mime_type === 'image/svg'):
92 $extractor = new SVG();
93 break;
94 case (str_contains($mime_type, 'video')):
95 $extractor = new Video();
96 break;
97 case ($mime_type === 'application/pdf'):
98 $extractor = new PDF();
99 break;
100 }
101
102 $target_format = $extractor->getTargetFormat();
103 $target_background = $extractor->getBackground();
104 $alpha_channel = $extractor->getAlphaChannel();
105 $remove_color = $extractor->getRemoveColor();
106 $resolution = $extractor->getResolution();
107
108 // General Image Settings
109 $img->setResolution($resolution, $resolution);
110 $img->setBackgroundColor($target_background);
111
112 // Read source image
113 try {
114 $img = $extractor->readImage($img, $stream, $for_definition);
115 } catch (\ImagickException) {
116 // due to possible security risks, gs disabled access to files, see e.g. https://en.linuxportal.info/tutorials/troubleshooting/how-to-fix-errors-from-imagemagick-imagick-conversion-system-security-policy
117 return;
118 }
119
120 // Size Settings
121 $max_size = $for_definition->getMaxSize();
122 $img->resetIterator();
123
124 // create gif if needed
125 $gif = $target_format === 'gif' ? new \Imagick() : null;
126 if ($gif !== null) {
127 $gif->setFormat('GIF');
128 }
129
130 for ($x = 0; ($x < $for_definition->getMaxPages() && $x < $img->getNumberImages()); $x++) {
131 $img->setIteratorIndex($x);
132 $img->setImageAlphaChannel($alpha_channel);
133 $img->setImageBackgroundColor($target_background);
134 $img->setImageFormat($target_format);
135
136 if ($remove_color !== null) {
137 $img->transparentPaintImage($remove_color, 0, 0, false);
138 }
139
140 [$columns, $rows] = $this->calculateWidthHeightFromImage($img, $max_size);
141
142 if (!$this->high_quality) {
143 $yield = $img->thumbnailImage(
144 (int) $columns,
145 (int) $rows,
146 true,
147 $for_definition->isFill()
148 );
149 } else {
150 $img->setImageResolution($resolution, $resolution);
151 $img->setImageCompression(\Imagick::COMPRESSION_JPEG);
152 $img->setImageCompressionQuality($quality);
153 $img->stripImage();
154
155 $yield = $img->resizeImage(
156 (int) $columns,
157 (int) $rows,
158 \Imagick::FILTER_MITCHELL,
159 1
160 );
161 }
162
163 if ($yield && $gif === null) {
164 yield new Result(
165 $for_definition,
166 Streams::ofString($img->getImageBlob()),
167 $x,
168 $for_definition->persist()
169 );
170 } elseif ($yield && $gif !== null) {
171 $gif->addImage($img->getImage());
172 $gif->setImageDelay(50);
173 }
174 }
175
176 if ($gif !== null) {
177 $gif->setImageFormat('gif');
178 $gif->setIteratorIndex(0);
179 $gif->setImageIterations(0); // 0 means infinite loop
180 [$columns, $rows] = $this->calculateWidthHeightFromImage($gif, $max_size);
181 $gif->thumbnailImage(
182 (int) $columns,
183 (int) $rows,
184 true,
185 $for_definition->isFill()
186 );
187
188 yield new Result(
189 $for_definition,
190 Streams::ofString($gif->getImagesBlob()),
191 1,
192 $for_definition->persist()
193 );
194 $gif->destroy();
195 }
196 $img->destroy();
197 }
198}
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
processStream(FileInformation $information, FileStream $stream, FlavourDefinition $for_definition)
dependsOnEngine()
Return the class name of the Engine that is required for this Machine to work.
canHandleDefinition(FlavourDefinition $definition)
Check if a corresponding configuration can be processed by this Machine.
The base interface for all filesystem streams.
Definition: FileStream.php:32
if(!file_exists('../ilias.ini.php'))