@@ -34,7 +34,7 @@ protected function autoOrient(string $file, array $options)
3434 protected function blur (string $ file , array $ options )
3535 {
3636 if ($ options ['blur ' ] !== false ) {
37- return '-blur 0x ' . $ options ['blur ' ];
37+ return '-blur ' . escapeshellarg ( ' 0x ' . $ options ['blur ' ]) ;
3838 }
3939 }
4040
@@ -61,7 +61,21 @@ protected function coalesce(string $file, array $options)
6161 */
6262 protected function convert (string $ file , array $ options ): string
6363 {
64- return sprintf ($ options ['bin ' ] . ' "%s" ' , $ file );
64+ $ command = escapeshellarg ($ options ['bin ' ]);
65+
66+ // limit to single-threading to keep CPU usage sane
67+ $ command .= ' -limit thread 1 ' ;
68+
69+ // add JPEG size hint to optimize CPU and memory usage
70+ if (F::mime ($ file ) === 'image/jpeg ' ) {
71+ // add hint only when downscaling
72+ if ($ options ['scaleWidth ' ] < 1 && $ options ['scaleHeight ' ] < 1 ) {
73+ $ command .= ' -define ' . escapeshellarg (sprintf ('jpeg:size=%dx%d ' , $ options ['width ' ], $ options ['height ' ]));
74+ }
75+ }
76+
77+ // append input file
78+ return $ command . ' ' . escapeshellarg ($ file );
6579 }
6680
6781 /**
@@ -162,7 +176,7 @@ public function process(string $file, array $options = []): array
162176 */
163177 protected function quality (string $ file , array $ options ): string
164178 {
165- return '-quality ' . $ options ['quality ' ];
179+ return '-quality ' . escapeshellarg ( $ options ['quality ' ]) ;
166180 }
167181
168182 /**
@@ -177,7 +191,7 @@ protected function resize(string $file, array $options): string
177191 {
178192 // simple resize
179193 if ($ options ['crop ' ] === false ) {
180- return sprintf ( ' -resize %sx%s! ' , $ options ['width ' ], $ options ['height ' ]);
194+ return ' -thumbnail ' . escapeshellarg ( sprintf ( ' %sx%s! ' , $ options ['width ' ], $ options ['height ' ]) );
181195 }
182196
183197 // focus cropping
@@ -201,8 +215,9 @@ protected function resize(string $file, array $options): string
201215 // translate the gravity option into something imagemagick understands
202216 $ gravity = $ gravities [$ options ['crop ' ]] ?? 'Center ' ;
203217
204- $ command = sprintf ('-resize %sx%s^ ' , $ options ['width ' ], $ options ['height ' ]);
205- $ command .= sprintf (' -gravity %s -crop %sx%s+0+0 ' , $ gravity , $ options ['width ' ], $ options ['height ' ]);
218+ $ command = '-thumbnail ' . escapeshellarg (sprintf ('%sx%s^ ' , $ options ['width ' ], $ options ['height ' ]));
219+ $ command .= ' -gravity ' . escapeshellarg ($ gravity );
220+ $ command .= ' -crop ' . escapeshellarg (sprintf ('%sx%s+0+0 ' , $ options ['width ' ], $ options ['height ' ]));
206221
207222 return $ command ;
208223 }
@@ -218,9 +233,10 @@ protected function resize(string $file, array $options): string
218233 protected function save (string $ file , array $ options ): string
219234 {
220235 if ($ options ['format ' ] !== null ) {
221- $ file = basename ($ file ) . '. ' . $ options ['format ' ];
236+ $ file = pathinfo ($ file, PATHINFO_DIRNAME ) . ' / ' . pathinfo ( $ file , PATHINFO_FILENAME ) . '. ' . $ options ['format ' ];
222237 }
223- return sprintf ('-limit thread 1 "%s" ' , $ file );
238+
239+ return escapeshellarg ($ file );
224240 }
225241
226242 /**
@@ -232,6 +248,14 @@ protected function save(string $file, array $options): string
232248 */
233249 protected function strip (string $ file , array $ options ): string
234250 {
235- return '-strip ' ;
251+ if (F::extension ($ file ) === 'png ' ) {
252+ // ImageMagick does not support keeping ICC profiles while
253+ // stripping other privacy- and security-related information,
254+ // such as GPS data; so discard all color profiles for PNG files
255+ // (tested with ImageMagick 7.0.11-14 Q16 x86_64 2021-05-31)
256+ return '-strip ' ;
257+ }
258+
259+ return '' ;
236260 }
237- }
261+ }
0 commit comments