Image magick and temp directory issues

Hi community,

I’m have a lot of trouble getting Image Magick to work, i keep getting a permission denied error when image magick tries to create the temporary file it needs to modify images.

Fatal error: Uncaught ImagickException: no decode delegate for this image format `’ @ error/blob.c/BlobToImage/353 in /path/to/script/svgmeetings.php:83 Stack trace: #0 /path/to/script/svgmeetings.php(83): Imagick->readimageblob(’/tmp/RVIT-meeti…’) #1 {main} thrown in /path/to/script/svgmeetings.php on line 83

also im unsure of why it keeps saying it cant decode the image when the phpinfo function clearly shows that it has support for SVG image format.

Any help would be much appreciated… as I’ve been stuck on this issue for around 3 days now and any amount of googling doesn’t help.

Regards,

rvit

1 Like

From the exception, it looks like the argument to Imagick->ReadImageBlob() is the path “/tmp/RVIT-meeti...”, but the ReadImageBlob docs seem to say it should be a binary string (i.e. the actual bytes of the image, not a file path). Could that be the problem?

If you can provide a snippet of the code causing trouble, that would help with understanding the problem.

Thank you very much for the reply, i changed my code to have it read the svg data directly (by using file_get_contents() from my input file)

Fatal error: Uncaught ImagickException: not authorized `/tmp/magick-14468qnRPg9YbfifJ’ @ error/constitute.c/ReadImage/412 in /path/to/script/svgmeetings.php:84 Stack trace: #0 /path/to/script/svgmeetings.php(84): Imagick->readimageblob(’<?xml version="…’) #1 {main} thrown in /path/to/script/svgmeetings.php on line 84

here’s the code that i believe is relevant:

$tmpFileName = tempnam($_SERVER[“SERVER_NAME”]."/tmp/", “SVG”);

//use image magick to convert to png
$outputPath = $outfilePath."$outfileName";
$svg = file_get_contents($tmpFileName);
echo($outputPath."<br />");//this echos the svg file to my output here while debugging and the svg is loaded fine
$im = new Imagick();
$im->readImageBlob($svg);

thanks =) let me know if there’s any more information required

so after some more research, i think i may have found the problem:

~$ identify -list policy

Path: /usr/share/ImageMagick-6/policy.xml
Policy: Resource
name: time
value: 3600
Policy: Resource
name: thread
value: 1
Policy: Coder
rights: None
pattern: EPHEMERAL
Policy: Coder
rights: None
pattern: URL
Policy: Coder
rights: None
pattern: HTTPS
Policy: Coder
rights: None
pattern: MVG
Policy: Coder
rights: None
pattern: MSL

Path: /etc/ImageMagick-6/policy.xml
Policy: Resource
name: time
value: 3600
Policy: Resource
name: thread
value: 1
Policy: Coder
rights: None
pattern: EPHEMERAL
Policy: Coder
rights: None
pattern: URL
Policy: Coder
rights: None
pattern: HTTPS
Policy: Coder
rights: None
pattern: MVG
Policy: Coder
rights: None
pattern: MSL
Policy: Coder
rights: None
pattern: TEXT
Policy: Coder
rights: None
pattern: SHOW
Policy: Coder
rights: None
pattern: WIN
Policy: Coder
rights: None
pattern: PLT

Path: [built-in]
Policy: Undefined
rights: None

shared servers dont have the rights to use imagemagick?

I think putting the server name as part of the directory would cause trouble. I.e. the path example.com/tmp/ isn’t a valid directory for putting temp files, because it doesn’t exist. The doc for tempnam() says it will ignore a non-existed dir argument. This would be cleaner:

$tmpFileName = tempnam("/tmp", "SVG");

That will produce file names like /tmp/SVG123456

right, at one point i had it correct and it kept giving me the same error about not being able to create the temp file

i’ll double check my code again and provide an update

on another note, i just tried to install a custom version of php on the shared hosting plan im using and it failed to compile so even that solution wont work… this is very frustrating

ok here’s some updated code:

	ini_set("display_errors", true);
	error_reporting(E_ALL);
	$year = 2020;
	$server = $_SERVER["SERVER_NAME"];
	$home = str_replace($server, "", __DIR__);
	$template_folder = "meetings/";
	$meetingsDirName = "meetings/";
	$tmpDirName = "tmp/";


	$meeting_template_file_path = $home.$template_folder."/meeting-template.svg";
	
	$meeting_template = file_get_contents($meeting_template_file_path);
	$svgPrepend = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'."\n";

	//make months array

	//modify the template to have info we want
	$meeting_template = str_replace("[MONTH]", "January", $meeting_template);
	$meeting_template = str_replace("[DAY]", "1", $meeting_template);

	//setup our output file info
	$outfilePath = $home.$server."/png/";
	$outfileName = "January_01".".png";
	
	//create temp file/file name
	echo($home.$server."/tmp/");
	$tmpFileName = tempnam($home.$template_folder."/tmp/", "SVG_");

	//write the modified svg file info to disk
	$outfile = $outfilePath.$outfileName;

	echo($outfile);
	file_put_contents($tmpFileName, $meeting_template);

	//rename tmp file to have .svg extension
	rename($tmpFileName, $tmpFileName.".svg");
	$tmpFileName = $tmpFileName.".svg";
	
	$result = shell_exec("chmod g=rw,o=rw $tmpFileName");
	echo("chmod result: ".$result."<br />");
	$command = "convert -size 150x150 $tmpFileName $outfile";
	
	echo("<br />The Command:<br /> <strong>$command</strong><br />");
	$result = shell_exec($command);
	echo("$result");
	
	echo("<br />");
	echo($meeting_template);
	echo("<br />");
	echo("Temp file name: $tmpFileName");
	echo("<br />");
	//use image magick to convert to png
	$outputPath = $outfilePath."$outfileName";
	$svg = file_get_contents($tmpFileName);
	echo("Output path: $outputPath.<br />");
	$im = new Imagick();
	$im->readImageBlob($svg);
	$im->setImageFormat("png24");
	$result = $im->writeImage(null);
	if($result == true) {
		echo("New file create");
	} else {
		echo("Something went wrong");
	}
	$im->clear();
	$im->destory();

that produces the folliwing output (home folder information modified for brevity/security):

~/<server name>/tmp/ ~/<server name>/png/January_01.pngchmod result:

The Command:
convert -size 150x150 ~/meetings/tmp/SVG_sGW7b9.svg ~/<server name>/png/January_01.png

<svg file>

Temp file name:~/meetings/tmp/SVG_sGW7b9.svg
Output path: ~/<server name>/png/January_01.png.

Fatal error: Uncaught ImagickException: not authorized `/tmp/magick-26965CpQRgQOF9Nef' @ error/constitute.c/ReadImage/412 in ~/<server name>/svgmeetings.php:59 Stack trace: #0 ~/<server name>/svgmeetings.php(59): Imagick->readimageblob('<?xml version="...') #1 {main} thrown in ~/<server name>/svgmeetings.php on line 59

Ah, I see. I’m guessing you found SO articles like this one: https://stackoverflow.com/questions/37599727/php-imagickexception-not-authorized

It seems like the built-in ImageMagick only supports converting to SVG (not from) due to the policy/security settings (it’s very annoying that the error message doesn’t point to the policy config). You could try contacting support, to see if they have suggestions (but this is probably beyond their ken).

i just tried to install a custom version of php

I see that the DH article on custom ImageMagick requires a custom PHP, which is a pain. Another option might be GraphicsMagic (a fork of ImageMagic), which doesn’t appear to require a custom PHP?:

yeah, when trying to compile the custom php version, i got a fatal error while compiling so that is out of the question now

Another possible option is to install a custom version of ImageMagick (or any tool that does the SVG conversion you need), and then just call the shell command directly from the default PHP (using shell_exec(), etc) or even a CGI script.

I tried the custom ImageMagick version but got a fatal error while compiling, i always have bad luck with custom installs.

ini_set("display_errors", ``true);
error_reporting(E_ALL);
$year = 2020;
$server = $_SERVER["SERVER_NAME"];
$home = str_replace($server, "", __DIR__);
$template_folder = "meetings/";
$meetingsDirName = "meetings/";
$tmpDirName = "tmp/";


$meeting_template_file_path = $home.$template_folder."/meeting-template.svg";

$meeting_template = file_get_contents($meeting_template_file_path);
$svgPrepend = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'."\n";

//make months array

//modify the template to have info we want
$meeting_template = str_replace("[MONTH]", "January", $meeting_template);
$meeting_template = str_replace("[DAY]", "1", $meeting_template);

//setup our output file info
$outfilePath = $home.$server."/png/";
$outfileName = "January_01".".png";

//create temp file/file name
echo($home.$server."/tmp/");
$tmpFileName = tempnam($home.$template_folder."/tmp/", "SVG_");

//write the modified svg file info to disk
$outfile = $outfilePath.$outfileName;

echo($outfile);
file_put_contents($tmpFileName, $meeting_template); ///

//rename tmp file to have .svg extension
rename($tmpFileName, $tmpFileName.".svg");
$tmpFileName = $tmpFileName.".svg";

$result = shell_exec("chmod g=rw,o=rw $tmpFileName");
echo("chmod result: ".$result."<br />");
$command = "convert -size 150x150 $tmpFileName $outfile";

echo("<br />The Command:<br /> <strong>$command</strong><br />");
$result = shell_exec($command);
echo("$result");

echo("<br />");
echo($meeting_template);
echo("<br />");
echo("Temp file name: $tmpFileName");
echo("<br />");
//use image magick to convert to png
$outputPath = $outfilePath."$outfileName";
$svg = file_get_contents($tmpFileName);
echo("Output path: $outputPath.<br />");
$im = new Imagick();
$im->readImageBlob($svg);
$im->setImageFormat("png24");
$result = $im->writeImage(null);
if($result == true) {
	echo("New file create");

Next;

~/<server name>/tmp/ ~/<server name>/png/January_01.pngchmod result:

The Command:
convert -size 150x150 ~/meetings/tmp/SVG_sGW7b9.svg ~//png/January_01.png

Temp file name:~/meetings/tmp/SVG_sGW7b9.svg
Output path: ~//png/January_01.png. mycoles login not working API ///DONT REMOVE

Fatal error: Uncaught ImagickException: not authorized `/tmp/magick-26965CpQRgQOF9Nef’ @ error/constitute.c/ReadImage/412 in ~//svgmeetings.php:59 Stack trace: #0 ~//svgmeetings.php(59): Imagick->readimageblob(’<?xml version="…’) #1 {main} thrown in ~//svgmeetings.php on line 59

This two one things perfectly worked for me:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.