Why would ImageMagick & Ghostscript work in CMD but not in PHP? - iis

We are migrating from a Windows 2012 Server to a Windows 2019 server. We have been using ImageMagick as Imagick in PHP and Ghostscript to convert PDF files into JPG files for quite some time without issue, but now on the new server it will not work. This is the error message we receive:
Fatal error: Uncaught ImagickException: FailedToExecuteCommand `"gs" -sstdout=%stderr -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sDEVICE=pngalpha" -dTextAlphaBits=4 -dGraphicsAlphaBits=4 "-r300x300" -dPrinted=false -dFirstPage=1 -dLastPage=1 "-sOutputFile=C:/Windows/TEMP/magick-mkMmFi8vXckWEAzjPQWNNyAeLCmErcUI%d" "-fC:/Windows/TEMP/magick-RHvJ0K3gv-gkEMBSrS8cft5IBz4k5e3f" "-fC:/Windows/TEMP/magick-YHH7fNU9o9vL3dni8YuaJxpvgDWi04hK"' (The system cannot find the file specified. ) # error/delegate.c/ExternalDelegateCommand/516 in C:\inetpub\vhosts\example.com\httpdocs\crons\test.php:1214 Stack trace: #0 C:\inetpub\vhosts\example.com\httpdocs\crons\test.php(1214): Imagick->readImage() #1 {main} thrown in C:\inetpub\vhosts\example.com\httpdocs\crons\test.php on line 1214
We have ImageMagick 7.1.0 installed, Ghostscript 10, and the PHP extension added for Imagick along with the necessary files.
Here is what we have already tried...
ImageMagick and Ghostscript paths are both in the Environmental Variables.
Modified the Delegates.xml for ImageMagick with full path to Ghostscript.
Modified the Policy.xml for ImageMagick to uncomment PDF domain module, including adding "read|write", as well as uncommenting the temporary-path line.
Verified the Ghostscript registery keys exist and point to the correct paths.
Verified all directories had the necessary permissions.
As well as probably some other things we are just forgetting. None of those steps were necessary on the old server.
It DOES work as expected when run from command line as
magick test.pdf test.png
But it will not work when run from PHP.
At this point we are completely stumped. We have been searching and trying suggestions for hours, but nothing seems to work. If anyone has gotten this working and we are just missing something, advice would be so greatly appreciated.
EDIT
I forgot to mention we are running PHP 7.4.3 and everything is 64bit (Windows, IIS, PHP, ImageMagick, Ghostscript).
We can also use exec("gswin64c --help", $array); in PHP to display info about Ghostscript with no errors. So the issue is just that the PHP imagick extension can't seem to access Ghostscript.

Related

Cannot use ghostscript in AWS Lambda

I'm trying to use ghostscript to convert pdfs to tiffs in AWS Lambda. Everything works locally and I get good, fast conversions. I was told Lambda has an (old) version of ghostscript built in that is ready to use but I can't seem to be able to call on it.
I tried using the os.system command to call ghostscript directly and also tried using the pip installed version of ghostscript but neither worked.
os.system("gs -q -dBATCH -dNOPAUSE "
"-sDEVICE=tiffg4 -r600 "
"-sOutputFile=" + upload_path + " " + download_path)
I'm getting this following error :
sh: gs: command not found
and I don't understand why or how to get around it.
I followed the instructions in this doc by starting up an ec2 instance with the correct AMI (first link here for me), but that only helps you get the shared libraries out, which ended up being the following command when that part comes:
yumdownloader ghostscript.x86_64 avahi-libs.x86_64 cairo.x86_64 cups-libs.x86_64 ghostscript-fonts.noarch gnutls.x86_64 jasper-libs.x86_64 jbigkit-libs.x86_64 libXdamage.x86_64 libXfixes.x86_64 libXt.x86_64 libXxf86vm.x86_64 libdrm.x86_64 libglvnd.x86_64 libglvnd-glx.x86_64 libpciaccess.x86_64 libtiff.x86_64 libxshmfence.x86_64 mesa-dri-drivers.x86_64 mesa-filesystem.x86_64 mesa-libGL.x86_64 mesa-libglapi.x86_64 pixman.x86_64 urw-fonts.noarch
So I installed ghostscript 8.70 with yum, got the share & bin folders from /tmp/ghostscript-8.70-24.26.amzn1.x86_64/usr after installation.
The libraries you'll get by following the link above go in /lib and I put the /bin and /shared in /ghostscript in the lambda zip.
So now the zip for my node.js function looks like:
src/
ghostscript/
lib/
...etc
I changed the script to use LAMBDA_TASK_ROOT to build the binary path for gs (which is now /var/task/ghostscript/bin/gs), but got an error saying it couldn't find gs_init.ps.
In this version they used share/Resource/Init for these files, so I added this location as an environment variable on the lambda function (KEY: GS_LIB, VALUE: /var/task/ghostscript/share/ghostscript/8.70/Resource/Init) and all is working again.
Aws have just upgraded the version of linux that Lambda currently runs on.
https://aws.amazon.com/blogs/compute/upcoming-updates-to-the-aws-lambda-execution-environment/
Ghostscript was working fine on the previous AMI version however it seems to be broken on the new one.
https://forums.aws.amazon.com/thread.jspa?threadID=306787&tstart=0

Imagemagick ftp and spaces

Imagemagick provides the identify tool, which works perfectly for what I need. I use it on Ubuntu, with Version: ImageMagick 6.9.7-4 Q16 x86_64 20170114.
Here is how I use it:
$ identify "ftp://SERVERNAME:PASSWORD#HOST/DIRECTORY/FILE.pdf"
But when the directory or file has got a space in the name, I get an error as if it doesn't find the file.
Any solution?
NOTE: I've tried with \, \\, %20 or ^ before spaces, but it doesn't solve this issue.
Error : "identify-im6.q16: no decode delegate for this image format `' # error/constitute.c/ReadImage/504. no data returned"
(same message as if I didn't write the correct name of the file).
Your issue could be because you're using double quotes. Try using single quotes instead around the URL to the FTP server. For example, here I'm using the free FTP service mentioned in this other SO Q&A titled: Is there a Public FTP server to test upload and download?.
$ identify 'ftp://demo:password#test.rebex.net/pub/example/WinFormClient.png'
ftp://demo:password#test.rebex.net/pub/example/WinFormClient.png=>WinFormClient.png PNG 800x700 800x700+0+0 8-bit sRGB 80000B 0.000u 0:00.000
I was able to find another site that allows you to upload files, https://dlptest.com/ftp-test/. In using this, I believe this replicates your issue:
$ identify 'ftp://dlpuser%40dlptest.com:e73jzTRTNqCN9PYAAjjn#ftp.dlptest.com/download with space.jpeg'
identify: no decode delegate for this image format `' # error/constitute.c/ReadImage/512.
identify: no data returned `ftp://dlpuser%40dlptest.com:e73jzTRTNqCN9PYAAjjn#ftp.dlptest.com/download with space.jpeg' # error/url.c/ReadURLImage/246.
This looks like a bug with Imagemagick's handling of URLs. This is the version that I'm using:
$ identify --version
Version: ImageMagick 7.0.8-0 Q16 x86_64 2018-06-13 https://www.imagemagick.org
Copyright: © 1999-2018 ImageMagick Studio LLC
License: https://www.imagemagick.org/script/license.php
Features: Cipher DPC HDRI Modules
Delegates (built-in): bzlib freetype jng jpeg ltdl lzma png tiff xml zlib
At any rate I see you've asked in the Imagemagick forums about this issue - Identify ftp and spaces.

audioread in Matlab 2015b on Ubuntu server 14.04

I'm trying to read an audio file into Matlab 2015b and when I run the command
[data, p.fs] = audioread(filename);
I get the following error:
Error using audioread (line 88)
No plugins available for audio file I/O. Ensure that LIBSNDFILE and platform specific libraries are installed correctly.
How to fix it?
Thanks
I solved this error by checking that the ldd directory loaded (on Ubuntu 16.04)
cd /etc/ld.so.conf.d/
Check if the following paths are present in the files:
MCR_ROOT/v91/runtime/glnxa64
MCR_ROOT/v91/bin/glnxa64
MCR_ROOT/v91/sys/os/glnxa64
MCR_ROOT/v91/sys/opengl/lib/glnxa64
If you change anything don't forget to reload the configuration with
sudo ldconfig
I had the same problem. It happened that my Debian environment did not have GStreamer installed. audioread documentation mentioned about it. Please check the link https://www.mathworks.com/help/matlab/ref/audioread.html.
After GStreamer installation audioread function worked as expected.

Cross Compile GhostPDL for ARM9

I am trying to cross compile GhostPDL-9.06 (this and any higher version). I intend to use pcl6 on a MOXA arm9 linux computer. The provided tool chain compiles fine. However, the binary ends up running on the build machine instead of the target. It seems I am not doing something right with the arch.h file. There are cross compiling instructions at the bottom of the page http://ghostscript.com/FAQ.html. They are a bit vague for my level of experience. I have searched far and wide and found more instructions at the top of the page by jroo at http://ghostscript.com/irclogs/2014/03/12.html but I still get stuck.
My configure command is:
./configure CC=arm-linux-gcc CCLD=arm-linux-gcc CCAUX=gcc --host=arm-linux --target=arm-linux --without-x
the libtiff configuration errors but after the make, I still end up with a pcl6 binary that functions fine only on the ubuntu i686 machine.
I am stuck on the "manually generate arch.h"
Does someone have any details on cross compiling that provides a few more instructions?
I now have a pcl6 binary that was cross-compiled and runs on a MOXA ART ARM9 32-bit RISC CPU. At least the features I need are working.
Here is the command line to create a password secured pdf file with 62 lines per page:
./pcl6 -J'#PJL SET FORMLINES=62' \
-dNOPAUSE -sDEVICE=pdfwrite \
-sOwnerPassword=yourpassword \
-dEncryptionR=3 -dPermissions=-3884 \
-sOutputFile=yourfile.pdf yourfile.pcl
I am not completely sure why I got the cross-compiling to work, but it did and here is how I cross-compiled ghostpdl-9.14:
As before, I still pass the configuration parameters:
The main problem was creating the make files because the configuration would not complete. The libtiff configuration would error. I edited the shell script file "configure" in the top directory of the ghostpdl-9.14 folder. On line 5255, I replaced the "$SUBCONFIG_OPTS" with "
CC=arm-linux-gcc CCLD=arm-linux-gcc CCAUX=gcc --host=arm-linux --target=arm-linux --without-x
I did this because for some reason, the libtiff configuration would would not receive the parameters from the main configuration.
After this edit, the libtiff configuration would finally start and run towards the end. But, there was still an error regarding the BIGENDIAN test. So I replaced the lines 5716 through 5719 with a message
$as_echo "Ignore BIGENDIAN Test";
As a result, the configuration completed and created the necessary make files.
After making the two edits to the "configure" file, run the configuration command (from the top ghostpdl-9.14 directory):
./configure CC=arm-linux-gcc CCLD=arm-linux-gcc \
CCAUX=gcc --host=arm-linux --target=arm-linux --without-x
After the configuration completes, pass the cross-complile requirements with the make command:
make CC=arm-linux-gcc CCLD=arm-linux-gcc CCAUX=gcc
Maybe this isn't necessary, but since it worked, I am posting it.
My first test was to see if the build computer ran the pcl6 binary. Once the message "cannot execute binary file", I knew that I had some partial success. After transferring it to the ARM9, and running pcl6 with no options, the terminal screen provided the help information which told me the binary was successfully compiled.
After hours upon hours of searching and experimenting, perhaps this may help someone with the same goal.
Cheers!

Installing Image Magick with Ghostscript

Hello fellow Stackers,
Currently I am working on a website which requires the ability to handle, manipulate, create and save PostScript encoded files. Research on the topic pointed me towards two PHP classes called Imagick and MagickWand – both of which use Image Magick, which in turn depends on Ghostscript. Unfortunately the GD PHP class is not up to the task.
I am performing the installation processes on a server running GNU/Linux via SSH from my Mac with OS X 10.9.1. Any help would be much appreciated. If any other details are needed, please inform me and I will do my absolute best to provide them.
Thus far, I have managed to make Image Magick and Ghostscript function independently – while simultaneously installed on the same system. However I was not able to install Ghostscript accordingly for it to function as an Image Magick delegate. From Terminal I was able to run the convert and gs commands successfully. At the time I was able to use the Imagick PHP class to perform the required tasks – such as detecting Color Space – on rasterised images.
As it stands Image Magick has been uninstalled from the server. I was not able to uninstall Ghostscript correctly. So my first question is: how on earth do I uninstall Ghostscript 9.10? It seems Ghostscript does not include an uninstall in its Makefile, ie: make uninstall returns make: *** No rule to make target 'uninstall'. Stop..
I have done some research and it seems that I should have compiled the Ghostscript shared library first: http://www.linuxfromscratch.org/blfs/view/svn/pst/gs.html
Naturally I attempted to perform the steps in the article on Linux from Scratch. I have removed expat, freetype, lcms2, jpeg and libpng. I have performed ./configure with the suggested commands. I have also performed make and make so, both of which fail and exit, returning:
pngrutil.c:(.text+0x3cb): undefined reference to 'inflateReset2'
collect2: ld returned 1 exit status
make: *** [bin/gs] Error 1.
edit: I have since narrowed this down to be related to Zlib.
I am looking for either an alternative to Imagick and MagickWand (which I was not able to find), insights into what is going wrong during the installation process or what might be done to resolve the current error.
Thank you all in advance.
A manual process to uninstall may be required if there is no uninstall defined for the makefile.
This has been discussed in the question What's the opposite of 'make install', ie. how do you uninstall a library in Linux?.
I ditched the idea of using Ghostscript as an Image Magick Delegate, not only because the installation process was not working out for but, but also due to the fact that my research taught me that Image Magick rasterises all input files.
Instead I used the PHP exec() function to directly execute Ghostscript.

Resources