Reputation: 1897
I am trying to use ImageMagick for some photo manipulation (crop for the moment). I succeed previously the desired outcome by using GD library for PHP (on my localhost) but now the hosting doesn't support it and they suggest me to use ImageMagick instead. The issue is that I can crop an image that it is stored locally :
<?php
$four = '4fingers1.jpg';
exec("convert $four -crop 100x100+100+100 test.jpg");
?>
<img src="test.jpg">
with no problem but when it comes from http sources (the actual purpose of my script) I receive no image. The code is the following (I post with a form the actual src of the image):
$src = $_POST['src'];
exec("convert $src -resize 720x720 resized.jpg"); // this is specified in the documentation
exec("convert resized.jpg -crop 100x100+100+100 final.jpg");
?>
<img src="final.jpg"> <!-- no image -->
<img src="resized.jpg"> <!-- no image -->
<img src="<?php echo $src; ?>"> <!-- alright -->
The documentation specify the following:
IM can also download an image that is published on the 'world wide web' by specifying that images URL. This basically provides a 'http:' image coder, which is why it works.
Link: http://www.imagemagick.org/Usage/files/#read
I've tried a lots of code snippets founded online and can't figure it out why is not working? I can use maybe something else to reach my purpose?
Upvotes: 4
Views: 2441
Reputation: 1897
The problem was that IM have a problem with the https protocol in my case. I've tested with a http image and everything was working fine so I made the following:
<?php
$src = $_POST['src'];
$src = preg_replace('/^https\:\/\//', 'http://', $src);
$src = escapeshellarg($src);
exec('convert ' . $src . ' resized.jpg 2>&1', $output, $returnval);
if($returnval !== 0) {
die('imagemagick error: ' . join("<br/>", $output));
}
?>
<img src="resized.jpg">
I have the image now displayed and I can start crop it and so on.
Upvotes: 0
Reputation: 157927
First I'm with the answer of Jon and the comment of Prisoner. You'll have to escape the $src POST var to prevent from shell command injection using escapeshellarg()
:
$src = escapeshellarg($_POST);
Further you should use the second param (output of command) and the third param (return value of command) and respect it.
Call exec()
like this:
exec("convert $src -resize 720x720 resized.jpg 2>&1", $output, $returnval);
if($returnval !== 0) {
die('imagemagick error: ' . join("<br/>", $output));
}
Now you are able to react on errors and you can see what's going wrong. Note that I've redirected stderr of imagemagick to stdout using shell redirection ( 2>&1
)
Upvotes: 0
Reputation: 437326
First of all, as Prisoner comments this code is vulnerable to shell argument injection. Basically anyone can manipulate the post parameters and cause you to execute any command line they want; this is potentially disastrous and should be addressed immediately!
One way to fix the security issue is use escapeshellarg
; this should also fix your "original" problem since there is no apparent reason for the command to fail. If the URL is valid and the argument is properly escaped it should just work.
Alternatively, you can solve both the security headache and your original problem by downloading the image yourself and saving it to a temporary file before calling IM:
$temp = tempnam(sys_get_temp_dir());
file_put_contents($temp, file_get_contents($url));
exec("convert ".escapeshellarg($temp)." -crop 100x100+100+100 test.jpg");
Upvotes: 4