depage-graphics
Toggle main menu visibility
Loading...
Searching...
No Matches
Imagemagick.php
Go to the documentation of this file.
1
<?php
2
10
11
namespace
Depage\Graphics\Providers;
12
22
class
Imagemagick
extends
\Depage\Graphics\Graphics
23
{
27
protected
$command
=
''
;
31
protected
$executable
;
35
protected
$timeout
= 0;
41
public
function
__construct
($options = [])
42
{
43
parent::__construct($options);
44
45
$this->executable = $options[
'executable'
] ??
null
;
46
$this->timeout = $options[
'timeout'
] ?? 0;
47
}
48
55
public
function
canRead
($ext)
56
{
57
return
parent::canRead($ext) || in_array($ext, [
'tif'
,
'tiff'
,
'pdf'
,
'eps'
]);
58
}
59
71
protected
function
crop
($width, $height, $x = 0, $y = 0)
72
{
73
if
(!$this->
bypassTest
($width, $height, $x, $y)) {
74
// '+' for positive offset (the '-' is already there)
75
$x = ($x < 0) ? $x :
'+'
. $x;
76
$y = ($y < 0) ? $y :
'+'
. $y;
77
78
$this->command .=
" -gravity NorthWest -crop {$width}x{$height}{$x}{$y}! -flatten"
;
79
$this->size = [$width, $height];
80
}
81
}
82
91
protected
function
resize
($width, $height)
92
{
93
$newSize = $this->
dimensions
($width, $height);
94
95
if
(!$this->
bypassTest
($newSize[0], $newSize[1])) {
96
$resizeAction = $this->
getResizeAction
($newSize[0], $newSize[1]);
97
98
$this->command .=
" $resizeAction {$newSize[0]}x{$newSize[1]}!"
;
99
100
$this->size = $newSize;
101
}
102
}
103
112
protected
function
thumb
($width, $height)
113
{
114
if
(!$this->
bypassTest
($width, $height)) {
115
$resizeAction = $this->
getResizeAction
($width, $height);
116
117
$this->command .=
" -gravity Center $resizeAction {$width}x{$height} -extent {$width}x{$height}"
;
118
$this->size = [$width, $height];
119
}
120
}
121
132
protected
function
thumbfill
($width, $height, $centerX = 50, $centerY = 50)
133
{
134
if
(!$this->
bypassTest
($width, $height)) {
135
$newSize = $this->
dimensions
($width,
null
);
136
$centerX = $centerX / -100 + 0.5;
137
$centerY = $centerY / -100 + 0.5;
138
139
if
($newSize[1] < $height) {
140
$newSize = $this->
dimensions
(
null
, $height);
141
$x = round(($width - $newSize[0]) * $centerX);
142
$y = 0;
143
}
else
{
144
$x = 0;
145
$y = round(($height - $newSize[1]) * $centerY);
146
}
147
$x = ($x < 0) ? $x :
'+'
. $x;
148
$y = ($y < 0) ? $y :
'+'
. $y;
149
150
$resizeAction = $this->
getResizeAction
($width, $height);
151
152
$this->command .=
" -gravity Center $resizeAction {$width}x{$height}^ -extent {$width}x{$height}{$x}{$y}"
;
153
$this->size = [$width, $height];
154
}
155
}
156
162
protected
function
getImageSize
(): array
163
{
164
$imageSize =
false
;
165
if
(is_callable(
'getimagesize'
)) {
166
$imageSize = getimagesize($this->input);
167
}
168
if
(!$imageSize) {
169
$pageNumber = $this->
getPageNumber
();
170
$identify = preg_replace(
'/convert$/'
,
'identify'
, $this->executable);
171
$command
=
"{$identify} -ping -format \"%wx%h\" "
. escapeshellarg($this->input) . $pageNumber;
172
$escapedCommand = str_replace(
'!'
,
'\!'
, escapeshellcmd(
$command
));
173
174
exec($escapedCommand .
' 2>&1'
, $commandOutput, $returnStatus);
175
if
($returnStatus === 0) {
176
$imageSize = explode(
'x'
, $commandOutput[0]);
177
}
else
{
178
$this->
unlock
();
179
180
throw
new \Depage\Graphics\Exceptions\Exception(implode(
"\n"
, $commandOutput));
181
}
182
}
183
184
return
$imageSize;
185
}
186
196
public
function
render
(
$input
,
$output
=
null
): void
197
{
198
parent::render(
$input
,
$output
);
199
200
$this->command =
''
;
201
$this->
processQueue
();
202
203
if
($this->otherRender && file_exists($this->output)) {
204
// do nothing file is already generated
205
} elseif (
206
$this->
bypass
207
&& $this->inputFormat == $this->outputFormat
208
) {
209
$this->
bypass
();
210
}
else
{
211
$background
= $this->
getBackground
();
212
$quality
= $this->
getQuality
();
213
$optimize
= $this->
getOptimize
();
214
$pageNumber = $this->
getPageNumber
();
215
216
$this->command =
"{$this->executable} {$background} ( -auto-orient '+profile' '*' -auto-orient "
. escapeshellarg($this->input) .
"{$pageNumber}{$this->command}"
;
217
$this->command .=
" ) -colorspace sRGB -flatten {$quality}{$optimize}"
;
218
219
$this->command .=
" {$this->outputFormat}:"
. escapeshellarg($this->output);
220
221
$this->
execCommand
();
222
223
if
($this->optimize) {
224
$this->
optimizeImage
($this->output);
225
}
226
}
227
228
parent::renderFinished();
229
}
230
238
protected
function
execCommand
()
239
{
240
$command
= str_replace(
'!'
,
'\!'
, escapeshellcmd($this->command));
241
242
$descriptorspec = [
243
0 => [
"pipe"
,
"r"
],
// stdin is a pipe that the child will read from
244
1 => [
"pipe"
,
"w"
],
// stdout is a pipe that the child will write to
245
2 => [
"pipe"
,
"w"
],
// stderr is pipe that the child will write errors to
246
];
247
$process = proc_open(
"exec "
.
$command
, $descriptorspec, $pipes);
248
249
// set pipes non blocking
250
stream_set_blocking($pipes[1],
false
);
251
stream_set_blocking($pipes[2],
false
);
252
253
$startTime = time();
254
$output
= [1 =>
""
, 2 =>
""
];
255
$terminated =
false
;
256
257
if
(is_resource($process)) {
258
// read stdin and stderr
259
while
(!feof($pipes[1]) && !feof($pipes[2])) {
260
for
($i = 1; $i < 3; $i++) {
261
$s = fgets($pipes[$i]);
262
$output
[$i] .= $s;
263
}
264
265
usleep(10000);
266
if
($this->timeout > 0 && time() - $startTime > $this->timeout) {
267
// terminate process of takes longer than timeout
268
proc_terminate($process);
269
$terminated =
true
;
270
}
271
}
272
273
for
($i = 0; $i < 3; $i++) {
274
fclose($pipes[$i]);
275
}
276
$returnStatus = proc_close($process);
277
}
278
279
if
($terminated) {
280
$this->
unlock
();
281
282
throw
new \Depage\Graphics\Exceptions\Exception(
"Conversion over timeout"
);
283
} elseif ($returnStatus != 0) {
284
$this->
unlock
();
285
286
throw
new \Depage\Graphics\Exceptions\Exception(
$output
[2]);
287
}
288
}
289
295
protected
function
getBackground
()
296
{
297
$background
=
"-size {$this->size[0]}x{$this->size[1]}"
;
298
299
if
($this->background[0] ===
'#'
) {
300
$background
.=
" -background {$this->background}"
;
301
} elseif ($this->background ==
'checkerboard'
) {
302
$background
.=
" -background none pattern:checkerboard"
;
303
}
else
{
304
if
($this->outputFormat ==
'jpg'
) {
305
$background
.=
" -background #FFF"
;
306
}
else
{
307
$background
.=
" -background none"
;
308
}
309
}
310
311
return
$background
;
312
}
313
318
protected
function
getQuality
()
319
{
320
if
(
321
$this->outputFormat ==
'jpg'
322
|| $this->outputFormat ==
'png'
323
|| $this->outputFormat ==
'webp'
324
) {
325
return
'-quality '
. parent::getQuality();
326
}
else
{
327
return
''
;
328
}
329
}
330
335
protected
function
getOptimize
()
336
{
337
$param =
" -strip"
;
338
339
if
($this->outputFormat ==
'jpg'
) {
340
$param .=
" -interlace Plane"
;
341
} elseif ($this->outputFormat ==
'png'
) {
342
$param .=
" -define png:format=png00"
;
343
} elseif ($this->outputFormat ==
"webp"
&& $this->inputFormat ==
"png"
) {
344
$param .=
" -define webp:lossless=true -define webp:image-hint=graph"
;
345
}
346
347
return
$param;
348
}
349
357
protected
function
getResizeAction
($width, $height)
358
{
359
if
($width <= 160 && $height <= 160) {
360
return
"-thumbnail"
;
361
}
else
{
362
return
"-resize"
;
363
}
364
}
365
}
366
367
/* vim:set ft=php sw=4 sts=4 fdm=marker et : */
Depage\Graphics\Graphics
Main graphics class.
Definition
Graphics.php:42
Depage\Graphics\Graphics\$background
$background
Image background string.
Definition
Graphics.php:74
Depage\Graphics\Graphics\$quality
$quality
Image quality string.
Definition
Graphics.php:78
Depage\Graphics\Graphics\processQueue
processQueue()
Process action queue.
Definition
Graphics.php:329
Depage\Graphics\Graphics\bypassTest
bypassTest($width, $height, $x=0, $y=0)
Tests if action would change current image.
Definition
Graphics.php:558
Depage\Graphics\Graphics\$input
$input
Input filename.
Definition
Graphics.php:46
Depage\Graphics\Graphics\$output
$output
Output filename.
Definition
Graphics.php:50
Depage\Graphics\Graphics\getPageNumber
getPageNumber()
getPageNumber
Definition
Graphics.php:540
Depage\Graphics\Graphics\dimensions
dimensions($width, $height)
Scales image dimensions.
Definition
Graphics.php:301
Depage\Graphics\Graphics\optimizeImage
optimizeImage($filename)
Opimizes final image through one of the optimization programs.
Definition
Graphics.php:382
Depage\Graphics\Graphics\bypass
bypass()
Runs bypass (copies file).
Definition
Graphics.php:586
Depage\Graphics\Graphics\unlock
unlock()
unlock
Definition
Graphics.php:414
Depage\Graphics\Graphics\$optimize
$optimize
Optimize output images.
Definition
Graphics.php:82
Depage\Graphics\Providers\Imagemagick
ImageMagick interface.
Definition
Imagemagick.php:23
Depage\Graphics\Providers\Imagemagick\getBackground
getBackground()
Generates background command.
Definition
Imagemagick.php:295
Depage\Graphics\Providers\Imagemagick\thumbfill
thumbfill($width, $height, $centerX=50, $centerY=50)
Thumb action.
Definition
Imagemagick.php:132
Depage\Graphics\Providers\Imagemagick\getQuality
getQuality()
Generates quality command.
Definition
Imagemagick.php:318
Depage\Graphics\Providers\Imagemagick\$executable
$executable
Imagemagick executable path.
Definition
Imagemagick.php:31
Depage\Graphics\Providers\Imagemagick\canRead
canRead($ext)
Checks if extension support reading file type.
Definition
Imagemagick.php:55
Depage\Graphics\Providers\Imagemagick\$timeout
$timeout
timeout after which the image conversion will be canceled
Definition
Imagemagick.php:35
Depage\Graphics\Providers\Imagemagick\getImageSize
getImageSize()
Determine size of input image.
Definition
Imagemagick.php:162
Depage\Graphics\Providers\Imagemagick\render
render($input, $output=null)
Main method for image handling.
Definition
Imagemagick.php:196
Depage\Graphics\Providers\Imagemagick\$command
$command
Imagemagick command string.
Definition
Imagemagick.php:27
Depage\Graphics\Providers\Imagemagick\getResizeAction
getResizeAction($width, $height)
Gets the resize action depending on target size.
Definition
Imagemagick.php:357
Depage\Graphics\Providers\Imagemagick\resize
resize($width, $height)
Resize action.
Definition
Imagemagick.php:91
Depage\Graphics\Providers\Imagemagick\crop
crop($width, $height, $x=0, $y=0)
Crop action.
Definition
Imagemagick.php:71
Depage\Graphics\Providers\Imagemagick\thumb
thumb($width, $height)
Thumb action.
Definition
Imagemagick.php:112
Depage\Graphics\Providers\Imagemagick\__construct
__construct($options=[])
graphics_graphicsmagick class constructor
Definition
Imagemagick.php:41
Depage\Graphics\Providers\Imagemagick\getOptimize
getOptimize()
Generates optimization parameters.
Definition
Imagemagick.php:335
Depage\Graphics\Providers\Imagemagick\execCommand
execCommand()
Executes ImageMagick command.
Definition
Imagemagick.php:238
Providers
Imagemagick.php
Generated on
for depage-graphics by
doxygen
1.18.0
For an overview of all docs, go to
docs.depage.net