2

I am using ImageMagick 6.7.7-10 2017-07-31 Q16 on Ubuntu 14.04, through Wand 0.4.4, Python 3.4.3 and Django 1.11. I am trying to create a jpg thumbnail of a pdf file.

On the command line, I can do this with no errors:

convert -thumbnail x300 -background white -alpha remove Lucy.pdf[0] output_thumbnail.jpg

But when I try to use wand on the same image I get this error:

Traceback (most recent call last):
  File "/home/mark/python-projects/memorabilia-project/memorabilia/models.py", line 24, in make_thumb
    pages = Image(blob = b)
  File "/home/mark/.virtualenvs/memorabilia/lib/python3.4/site-packages/wand/image.py", line 2742, in __init__
    self.read(blob=blob, resolution=resolution)
  File "/home/mark/.virtualenvs/memorabilia/lib/python3.4/site-packages/wand/image.py", line 2822, in read
    self.raise_exception()
  File "/home/mark/.virtualenvs/memorabilia/lib/python3.4/site-packages/wand/resource.py", line 222, in raise_exception
    raise e
wand.exceptions.MissingDelegateError: no decode delegate for this image format `' @ error/blob.c/BlobToImage/367

I looked at the delegates.xml file for ImageMagic in /etc, and there are entries for pdf files.

Thanks for any suggestions on how to get this conversion to work through wand.

Mark

I hacked a simple Python script from my django code to test wand with pdfs, and it gives the same error. I also tested whether Ghostscript is in the path, and printed out the results of convert -list delegates.

from wand.image import Image
from os.path import splitext
import uuid
import os
import hashlib

newname = "sam.jpg"
oldnames = ["16u.jpg", "Lucy.pdf", "Jimbo.tiff", "john_edmonds.pdf", ]
size = "200"
RESOLUTION = 200
test = "4"
TEST_DATA = "test_data/"

def test_delegate():
    print ("test_delegate")
    print(os.system("convert -list delegate"))

def test_gs():
    print ("test_gs")
    retval = os.system("gs --version")
    print (retval)

def read_image(file_name):
    f = open(file_name, 'rb')
    h = hashlib.sha256()
    buff_size = 128*1024
    for b in iter(lambda : f.read(buff_size), b""):
        h.update(b)
    computed_sha256 = h.hexdigest()
    f.close()
    print ("b="+str(len(b))+", computed_sha256="+computed_sha256)
    return b

def create_thumb(names):
    for img in names:
        img = TEST_DATA + img
        print(img)
        thumb_name, thumb_extension = os.path.splitext(img)
        thumb_extension = thumb_extension.lower()
        bytes = read_image(img)
        if thumb_extension in [".pdf",]:
            print("found pdf")
            #pages = Image(filename = img)
            pages = Image(blob = bytes)
            first_page = pages.sequence[0]
            image = Image(first_page)
        else:
            print("found image")
            #image = Image(filename=img)
            image = Image(blob = bytes)
        image.transform(resize="x"+size)
        image.format = "jpg"
        image.save(filename=thumb_name+"_thumb_"+test+".jpg")
        print("finished successfully")

def main():
    print("main")
    test_delegate()
    test_gs()
    create_thumb(oldnames)

if __name__ == '__main__':
    main()

The output from this program is as follows. It has the same missing delegates error. The same error also occurs with tiff files, but not with jpg files (the first test file is a jpg and the code processed the file and created the thumbnail image). The program also prints the version of GS, which is 9.10, so that is accessible from the program, and it prints out the delegates it found, which include pdfs.:

python thumbs.py
main
test_delegate

Path: /etc/ImageMagick/delegates.xml

Delegate                Command
-------------------------------------------------------------------------------
    blender =>          "blender" -b "%i" -F PNG -o "%o""\n"convert" -concatenate "%o*.png" "%o"
        cdr =>          "uniconvertor" "%i" "%o.svg"; mv "%o.svg" "%o"
        cgm =>          "ralcgm" -d ps -oC < "%i" > "%o" 2> "%Z"
 dng:decode =>          "ufraw-batch" --silent --create-id=also --out-type=png --out-depth=16 "--output=%u.png" "%i"
        dot =>          "dot" -Tsvg "%i" -o "%o"
        dvi =>          "dvips" -q -o "%o" "%i"
        eps<=>pdf       "gs" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 "-sDEVICE=pdfwrite" "-sOutputFile=%o" "-f%i"
        eps<=>ps        "gs" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sDEVICE=nodevice" "-sOutputFile=%o" "-f%i"
        fig =>          "fig2dev" -L ps "%i" "%o"
        hpg =>          "hp2xx" -q -m eps -f `basename "%o"` "%i";     mv -f `basename "%o"` "%o"
       hpgl =>          "if [ -e hp2xx -o -e /usr/bin/hp2xx ]; then     hp2xx -q -m eps -f `basename "%o"` "%i";     mv -f `basename "%o"` "%o";   else     echo "You need to install hp2xx to use HPGL files with ImageMagick.";     exit 1;   fi"
        htm =>          "html2ps" -U -o "%o" "%i"
       html =>          "html2ps" -U -o "%o" "%i"
      https =>          "curl" -s -k -o "%o" "https:%F"
       ilbm =>          "ilbmtoppm" "%i" > "%o"
        man =>          "groff" -man -Tps "%i" > "%o"
       miff<= show      "/usr/bin/display" -delay 0 -window-group %[group] -title "%l " "ephemeral:%i"
mpeg:decode =>          "ffmpeg" -v -1 -i "%i" -vframes %S -vcodec pam -an -f rawvideo -y "%u.pam" 2> "%Z"
        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"
        pnm<= ilbm      "ppmtoilbm" -24if "%i" > "%o"
        pov =>          "povray" "+i%i" -D0 "+o%o" +fn%q +w%w +h%h +a -q9 "-kfi%s" "-kff%n";"convert" -concatenate "%o*.png" "%o"
         ps<=>eps       "gs" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sDEVICE=epswrite" "-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"
         ps<= print     "lpr "%i"
       rgba<= rle       "rawtorle" -o "%o" -v "%i"
       scan =>          "scanimage" -d "%i" > "%o"
      scanx =>          "scanimage" > "%o"
      shtml =>          "html2ps" -U -o "%o" "%i"
        sid =>          "mrsidgeodecode" -if sid -i "%i" -of tif -o "%o" > "%u"
        svg =>          "rsvg-convert" -o "%o" "%i"
       tiff<= launch    "gimp" "%i"
        txt<=>ps        "enscript" -o "%o" "%i"
        wmf =>          "wmf2eps" -o "%o" "%i"
0
test_gs
9.10
0
test_data/16u.jpg
b=43597, computed_sha256=0bac89048bbbcfa75ad7d9dbc84eae42ff6b30c0a057dd76e180a205d9021b8d
found image
finished successfully
test_data/Lucy.pdf
b=61053, computed_sha256=6e108603ad4f6ae2e08b3d2a419a65d3cc1f60b788e9377be15b1926892189f8
found pdf
Traceback (most recent call last):
  File "thumbs.py", line 63, in <module>
    main()
  File "thumbs.py", line 60, in main
    create_thumb(oldnames)
  File "thumbs.py", line 44, in create_thumb
    pages = Image(blob = bytes)
  File "/home/mark/.virtualenvs/memorabilia/lib/python3.4/site-packages/wand/image.py", line 2742, in __init__
    self.read(blob=blob, resolution=resolution)
  File "/home/mark/.virtualenvs/memorabilia/lib/python3.4/site-packages/wand/image.py", line 2822, in read
    self.raise_exception()
  File "/home/mark/.virtualenvs/memorabilia/lib/python3.4/site-packages/wand/resource.py", line 222, in raise_exception
    raise e
wand.exceptions.MissingDelegateError: no decode delegate for this image format `' @ error/blob.c/BlobToImage/367
Exception ignored in: <bound method Image.__del__ of <wand.image.Image: (empty)>>
Traceback (most recent call last):
  File "/home/mark/.virtualenvs/memorabilia/lib/python3.4/site-packages/wand/resource.py", line 232, in __del__
  File "/home/mark/.virtualenvs/memorabilia/lib/python3.4/site-packages/wand/image.py", line 2767, in destroy
TypeError: object of type 'NoneType' has no len()

Maybe this simple python code will help someone give me a direction to go to solve this problem. However, I am beginning to suspect there is a bug in wand when one uses byte arrays instead of file names.

Thanks!

Mark

user1045680
  • 815
  • 2
  • 9
  • 19
  • I am not really that familiar with Wand. But often with other interfaces, Ghostscript needs to be in the PATH used by that interface. This often happens with PHP Imagick, for example. So be sure you have that set. Alternately, you can edit the delegates.xml file for PS and put the full path to Ghostscript. Note, your command line command is actually not proper syntax, though IM 6 is rather forgiving. Your should read the input before other commands. It should properly be `convert Lucy.pdf[0] -thumbnail x300 -background white -alpha remove output_thumbnail.jpg`. What was your Wand command? – fmw42 Nov 13 '17 at 21:11
  • The wand command is in the first traceback line, pages = Image(blob = b). Also, there is only one delegates.xml on my computer, and it has all the pdf and ps etc. entries. gs is also on the path in /usr/bin. I also checked with a simple python program to test gs. – user1045680 Nov 14 '17 at 16:45

1 Answers1

0

In your installed ImageMagick delegates.xml file, you will find:

  <delegate decode="ps:alpha" stealth="True" command="&quot;gs&quot; -sstdout=%%stderr -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 &quot;-sDEVICE=pngalpha&quot; -dTextAlphaBits=%u -dGraphicsAlphaBits=%u &quot;-r%s&quot; %s &quot;-sOutputFile=%s&quot; &quot;-f%s&quot; &quot;-f%s&quot;"/>

  <delegate decode="ps:cmyk" stealth="True" command="&quot;gs&quot; -sstdout=%%stderr -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 &quot;-sDEVICE=pamcmyk32&quot; -dTextAlphaBits=%u -dGraphicsAlphaBits=%u &quot;-r%s&quot; %s &quot;-sOutputFile=%s&quot; &quot;-f%s&quot; &quot;-f%s&quot;"/>

  <delegate decode="ps:color" stealth="True" command="&quot;gs&quot; -sstdout=%%stderr -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 &quot;-sDEVICE=pnmraw&quot; -dTextAlphaBits=%u -dGraphicsAlphaBits=%u &quot;-r%s&quot; %s &quot;-sOutputFile=%s&quot; &quot;-f%s&quot; &quot;-f%s&quot;"/>

  <delegate decode="ps" encode="eps" mode="bi" command="&quot;gs&quot; -sstdout=%%stderr -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 &quot;-sDEVICE=eps2write&quot; &quot;-sOutputFile=%o&quot; &quot;-f%i&quot;"/>

  <delegate decode="ps" encode="pdf" mode="bi" command="&quot;gs&quot; -sstdout=%%stderr -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 &quot;-sDEVICE=pdfwrite&quot; &quot;-sOutputFile=%o&quot; &quot;-f%i&quot;"/>

Where it has command="&quot;gs&quot;, change that to provide the full path to gs in place of gs; that is, command="&quot;path2/gs&quot;

Be sure that you change this in the installed file and not in the ImageMagick download directory. Reboot and see if that helps.

Sorry, this is my only suggestion. And again I am not really familiar with Wand. Apologies if it does not help.

P.S. Is ImageMagick in /usr/bin or /usr/local/bin. If the latter, is that also in your PATH environment variable. Sorry if this is obvious.

fmw42
  • 46,825
  • 10
  • 62
  • 80
  • I don't think is is a gs path issue, as the program above shows that the program can access gs. The program above also shows that it can access all the ImageMagick delegates for pdf. I think it is a bug in wand. Thanks! – user1045680 Nov 14 '17 at 21:52
  • You may be correct as I know nothing about Wand's usage. But you are getting the following error message `no decode delegate for this image format`, which usually means it cannot find the needed delegate. I am assuming it cannot find Ghostscript from Wand even though it can from ImageMagick directly. That is why I suggested trying to put the full path to Ghostscript into the delegates.xml file. – fmw42 Nov 14 '17 at 22:53
  • If you look at my last test run, you will see that the program can find GS, because it prints out the correct version (9.10). The test program also prints out all the delegates it can find, which include pdf. I also ran the same program, but had Wand read the same files from disk, as opposed to passing them in as binary blobs, and all the images are processed as expected. So, I am now more confident that there is a bug in wand when reading binary data as opposed to reading a file from the local drive. Thanks for your comments! – user1045680 Nov 15 '17 at 23:36