cloudfoundry/cflinuxfs2

Ghostscript support

Closed this issue · 11 comments

TL;DR: I suggest to add the ghostscript package to install-packages.sh.

I use Imagemagick to convert PDF documents to JPG images (thumbnails).

Imagemagick is installed, but converting PDF to JPG fails with following error:

[APP/PROC/WEB/0] ERR convert.im6: Postscript delegate failed `/home/vcap/app/tmp/abc/thumb/my_pdf.pdf': No such file or directory @ error/pdf.c/ReadPDFImage/677.
[APP/PROC/WEB/0] ERR convert.im6: no images defined `/home/vcap/tmp/tmp.jpg' @ error/convert.c/ConvertImageCommand/3044.

I'm absolutely sure that the file exits (I have added a check in code one line before executing the convert). I execute the following command which leads in the error posted above:
convert -size 150x150 /home/vcap/app/tmp/abc/thumb/my_pdf.pdf /home/vcap/tmp/tmp.jpg

After looking a bit into it, I think it is related to missing Ghostscript setup:

Imagemagick is a commonly used library to manipulate images. It is possibly the only real solutions to create PDF thumbnails in the Ruby on Rails world.

I'm using Swisscom Cloud Foundry and have reported this issue there already. They suggested me to open an issue here since it would help other users as well.

We have created an issue in Pivotal Tracker to manage this:

https://www.pivotaltracker.com/story/show/139223621

The labels on this github issue will be updated when the story is started.

dgodd commented

We have been looking into this and agree that converting images to PDF using imagemagick would require the stack to have ghostscript installed. However in our experiments, converting from pdf to jpg works. Are all pdf files giving you problems, or only some?

The disadvantage of adding ghostscript to the rootfs is that it is quite large, and would thus adversely affect everybody's performance. An alternative is to include the ghostscript lib files in a vendor directory and add it to your LIBPATH (potentially in your start command).

@dgodd: Thanks for your feedback.

Are all pdf files giving you problems, or only some?

I have tried several PDFs, but none of them worked on Swisscom CF. Probably you can attach a PDF which worked in your setup here?

An alternative is to include the ghostscript lib files in a vendor directory and add it to your LIBPATH (potentially in your start command).

You you have some guide / documentation how this could be done step-by-step?

dgodd commented

invoicesample.pdf

convert invoicesample.pdf invoicesample2.jpg

invoicesample2

Nope, this does not work on Swisscom CF. Just tried with your example file.

Just wondering: why does the convert command work in your case? convert is part of GhostScript. Are you sure GhostScript is not available in your setup?

dgodd commented

Actually convert is part of the imagemagick library, as opposed to the imagemagick gem. For certain use cases it uses ghostscript as a helper utility/library. You can see an example from your error convert.im6: Postscript delegate failed

Do you know what version of rootfs and buildpack is deployed on your swisscom CF?

Oh, my fault. You are of course absolutely right about the convert command. :)

I'll send this question to Swisscom CF support and let you know afterward.

Probably this does already answer a part of your question:

-------> Buildpack version 1.6.28
       Downloaded [file:///tmp/buildpacks/d8d0acd408bf7802e96fc425e5a4c933/dependencies/https___buildpacks.cloudfoundry.org_concourse-binaries_bundler_bundler-1.13.6.tgz]
-----> Compiling Ruby/Rails
       Downloaded [file:///tmp/buildpacks/d8d0acd408bf7802e96fc425e5a4c933/dependencies/https___buildpacks.cloudfoundry.org_concourse-binaries_ruby_ruby-2.3.1-linux-x64.tgz]
-----> Using Ruby version: ruby-2.3.1

Currently we are at cflinuxfs2-rootfs version 1.40.0 and provide ruby-buildpack 1.6.28 although everyone can set a custom buildpack by defining it in the manifest or as an argument.

I quickly tested the conversion myself. As expected it does not work due to the lack of ghostscript, but as soon as I provide it, it works just fine:

mkdir /home/vcap/tmp/bin
cp gs-920-linux_x86_64 /home/vcap/tmp/bin/gs
export PATH=$PATH:/home/vcap/tmp/bin
convert -verbose invoicesample.pdf invoicesample2.jpg
"gs" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sDEVICE=pngalpha" -dTextAlphaBits=4 -dGraphicsAlphaBits=4 "-r72x72"  "-sOutputFile=/tmp/magick-6aIIkfQh-%08d" "-f/tmp/magick-11pVh6ZA" "-f/tmp/magick-Pn49E19T"
/tmp/magick-6aIIkfQh-00000001 PNG 595x842 595x842+0+0 8-bit DirectClass 80KB 0.010u 0:00.009
invoicesample.pdf PDF 595x842 595x842+0+0 16-bit DirectClass 80KB 0.000u 0:00.000
invoicesample.pdf=>invoicesample2.jpg PDF 595x842 595x842+0+0 16-bit DirectClass 69.6KB 0.010u 0:00.010

I think convert -list delegate shows which delegate IM will be using for the conversion, here my output, which suggests that ghostscript will be used for pdf conversion:

convert -list delegate | grep pdf
        eps<=>pdf       "gs" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 "-sDEVICE=pdfwrite" "-sOutputFile=%o" "-f%i"
        pdf<=>eps       "gs" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sDEVICE=epswrite" "-sOutputFile=%o" "-f%i"
        pdf<=>ps        "gs" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sDEVICE=nodevice" "-sOutputFile=%o" "-f%i"
         ps<=>pdf       "gs" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sDEVICE=pdfwrite" "-sOutputFile=%o" "-f%i"

Taking into account, that this feature might not be used by many and that there might be some drawbacks (size). I guess it makes sense to simply provide ghostscript in a lib path with the code.

dgodd commented

@uwolfer We just tested @ampersand8 solution of installing a statically compiled gs version at app start, and our sample rails app can receive a pdf and generate a png thumbnail.

Please re-open if you need any more help

@ampersand8, @dgodd: Thank you, I've solved the issue this way.

Just for the record if anybody else is also looking how to get PDF thumbnails working on Cloud Foundry here a step-by-step guide based on the answers above:

  1. Download Ghostscript for Linux x86 (64 bit)
  2. Extract the binary
  3. Rename it to gs
  4. Add it to the folder bin/ in your application
  5. Prepend the following part to you command in manifest.yml: export PATH=$PATH:$PWD/bin/ &&

Hello, I have a similar issue. I'm trying to run a django application on Cloud Foundry using cflinuxfs3 stack and python buildpack. I'm trying to parse PDFs using camelot-py (which is dependent on Ghostscript), however I get "RuntimeError: Please make sure that Ghostscript is installed"

I tried the below method where I created a bin folder in the same folder as my manifest.yml and I placed gs in there but it didn't work I still get the same error. I would really appreciate any help I can get.

1. Download [Ghostscript for Linux x86 (64 bit)](https://ghostscript.com/download/gsdnld.html)

2. Extract the binary

3. Rename it to `gs`

4. Add it to the folder `bin/` in your application

5. Prepend the following part to you `command` in `manifest.yml`: `export PATH=$PATH:$PWD/bin/ && `