Imagick / imagick

🌈 The Imagick PHP extension 🌈
http://pecl.php.net/imagick
Other
540 stars 136 forks source link

php Imagick class throws exception when instantiated with uploaded SVG file #565

Open mind-bending-forks opened 2 years ago

mind-bending-forks commented 2 years ago

Description

When a file is uploaded, it is stored as a temporary file. Its location and other information is stored PHP $_FILES superglobal.

After an SVG file is uploaded, if an attempt is made to instantiate the Imagick class on the uploaded temporary file, this fails. An ImagickException is thrown, providing a message similar to:

PHP Notice: Failed to load Imagick: unable to open file `/tmp/magick-Yih2iBoUnU02Cx6aL0gNy27decidWSnO': No such file or directory @ error/constitute.c/ReadImage/614

The file path provided a imagick defined. It is not the path of the uploaded temporary file. An exception is not thrown for uploaded bitmap files. JPEG, PNG and GIF files have all been tested.

Related issues

System Info

Other

Instantiation of Imagick after upload of SVG files is working on a system running Ubuntu 16.04 and PHP 7.0, but I don't have direct access to it. I'll request further information about setup and report back when I have it.

Danack commented 2 years ago

Do you have as example SVG that fails to work? Uploading that here (or emailing it to me if it's not publicly shareable), would allow me to investigate on my computer.

For that file, can you try creating an Imagick object from it with a PHP command line script? That would make it easier to debug.

In particular, installing strace and running the PHP script through it with:

strace -f -s 256 php debug.php > strace_output_with_follow.txt 2>&1

Would show exactly which bit was failing.

My guess is that Imagick/ImageMagick is calling an external program to render the SVG to a bitmap, and that is failing....and then for some reason it's not falling back to the internal SVG renderer...

Also, please could you dump the results of Imagick::getVersion() here just in case that is relevant.

mind-bending-forks commented 2 years ago

It fails with this SVG: https://upload.wikimedia.org/wikipedia/commons/6/68/Climate_influence_on_terrestrial_biome.svg

The output of echo var_export(\Imagick::getVersion()); is

array (
  'versionNumber' => 1691,
  'versionString' => 'ImageMagick 6.9.11-60 Q16 x86_64 2021-01-25 https://imagemagick.org',
)

Command line script, debug.php:

<?php

try
{
  $imagick = new \Imagick('Climate_influence_on_terrestrial_biome.svg');
}
catch (\ImagickException $e)
{
  trigger_error($e->getMessage());
  exit(1);
}
$imagick->clear();
exit(0);

Output:

PHP Notice:  unable to open file `/tmp/magick-aDEhfQybvsUqDavZtiAxCo_RUVuu5Ue3': No such file or directory @ error/constitute.c/ReadImage/614 in /var/www/fepdb/test.php on line 9

I've got the output of strace -f -s 256 php debug.php > strace_output_with_follow.txt 2>&1. Let me just check its contents and how best to share it.

Danack commented 2 years ago

gist.github.com ?

mind-bending-forks commented 2 years ago

gist.github.com ?

I've emailed you.

Danack commented 2 years ago

Looking at the strace output, I'm pretty sure this is a difference between how ImageMagick is being installed on the different machines, and/or some related programs and isn't a problem with Imagick itself.

Before I spend any more time on this, can you remind me, does your company sponsor either PHP or Imagick?

Links to sponsor them are https://opencollective.com/phpfoundation and https://github.com/sponsors/Danack .

mind-bending-forks commented 2 years ago

Instantiation of Imagick after upload of SVG files is working on a system running Ubuntu 16.04 and PHP 7.0, but I don't have direct access to it. I'll request further information about setup and report back when I have it.

I got the details above wrong. It's older than that. Here are the details of the system it is working on:

So, the key difference between the failing and succeeding environments appears to be that imagemagick and librsvg2-2 and librsrvg2-common are installed on the one where it succeeds. My guess would have been that one of them provides rsvg-convert, specified in the delegates.xml file as a processor of SVG files. However, from bionic and up at least, this command appears to be provided by librsvg2-bin, which is not installed, so that's a bit confusing.

In any case, it seems likely that the installation of the php-imagick package on Ubuntu 22.04 is failing to specify and install dependencies required for at least minimal SVG support, most likely librsvg2-2 and librsrvg2-common, or possibly imagemagick itself, or maybe librsvg2-bin, and not providing a very helpful error message about it at present. At least, that's my guess.

I'll be able to check whether installing any of these resolves the problem next week.

mind-bending-forks commented 2 years ago

In any case, it seems likely that the installation of the php-imagick package on Ubuntu 22.04 is failing to specify and install dependencies required for at least minimal SVG support, most likely librsvg2-2 and librsrvg2-common, or possibly imagemagick itself, or maybe librsvg2-bin, and not providing a very helpful error message about it at present. At least, that's my guess.

I'll be able to check whether installing any of these resolves the problem next week.

I've now investigated:

  1. I first installed librsvg2-2, which also installs librsrvg2-common. This does not resolve the problem. The behaviour is the same. This installed the following packages: fontconfig libcairo-gobject2 libcairo2 libdatrie1 libgdk-pixbuf-2.0-0 libgdk-pixbuf2.0-bin libgdk-pixbuf2.0-common libgraphite2-3 libharfbuzz0b libpango-1.0-0 libpangocairo-1.0-0 libpangoft2-1.0-0 libpixman-1-0 librsvg2-common libthai-data libthai0 libxcb-render0 libxcb-shm0 libxrender1
  2. I then purged librsvg2-2, autoremoved its installed dependencies, and installed the imagemagick package instead. This installed the following packages: fontconfig hicolor-icon-theme imagemagick imagemagick-6.q16 libcairo2 libdatrie1 libdjvulibre-text libdjvulibre21 libgraphite2-3 libharfbuzz0b libilmbase25 libjxr-tools libjxr0 libmagickcore-6.q16-6-extra libnetpbm10 libopenexr25 libpango-1.0-0 libpangocairo-1.0-0 libpangoft2-1.0-0 libpixman-1-0 libthai-data libthai0 libwmflite-0.2-7 libxcb-render0 libxcb-shm0 libxrender1 netpbm This solved the problem. With the imagemagick package installed in addition to php-imagick, the debug script above works without error, as does instantiating the \Imagick class on an uploaded SVG file.

I conclude that either the imagemagick package, or one or more the following of its dependencies hicolor-icon-theme libdjvulibre-text libdjvulibre21 libilmbase25 libjxr-tools libjxr0 libmagickcore-6.q16-6-extra libnetpbm10 libopenexr25 libwmflite-0.2-7 netpbm is required for php-imagick to provide minimal support for SVG files.

My recommendation would be that the php-imagick Ubuntu package be updated to require imagemagick or whatever missing library dependency is required for SVG files, so that it 'just works'. Alternatively, if the php \Imagick class could be updated to provide a helpful and accurate message about why it is failing and what needs to be done about it when an SVG file (or any image file) is processed for which the required library files are not available to process it, rather than the confusing "unable to open file" message being thrown for a file the user knows nothing about, this could save a lot of bother.

@Danack I can provide you with relevant strace output for cases 1 and 2 above, if that helps.

teenwolf99 commented 23 hours ago

Being stuck on the same issue, when converting ODT file to thumbnail images and getting the ImagickException(code: 430): unable to open file: No such file or directory error.

Trying to figure out the right dependencies for the .odt format.

Ubuntu 22.04 php version: 8.2 php-imagick 3.7.0

Output for php -i |grep imagick

/etc/php/8.2/cli/conf.d/20-imagick.ini, imagick imagick module => enabled imagick module version => 3.7.0 imagick classes => Imagick, ImagickDraw, ImagickPixel, ImagickPixelIterator, ImagickKernel imagick.allow_zero_dimension_images => 0 => 0 imagick.locale_fix => 0 => 0 imagick.progress_monitor => 0 => 0 imagick.set_single_thread => 1 => 1 imagick.shutdown_sleep_count => 10 => 10 imagick.skip_version_check => 1 => 1

Works well with converting the PDF formats to images though.

mind-bending-forks commented 22 hours ago

@teenwolf99 As per the above thread, if the imagemagick package is not installed, you could try installing it and see if that helps. It appears that the imagemagick package or one of its dependencies must be installed for php-imagick to work with SVGs. That may be true of other file types too.