Ошибки преобразования pdf в jpg с помощью wand, Imagemagick и Django

Я использую ImageMagick 6.7.7-10 2017-07-31 Q16 на Ubuntu 14.04, через Wand 0.4.4, Python 3.4.3 и Django 1.11. Я пытаюсь создать миниатюру jpg файла pdf.

В командной строке я могу сделать это без ошибок:

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

Но когда я пытаюсь использовать палочку на том же изображении, я получаю эту ошибку:

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

Я просмотрел файл delegates.xml для ImageMagic в /etc, и там есть записи для pdf-файлов.

Спасибо за любые предложения о том, как заставить это преобразование работать через палочку.

Отметка

Я взломал простой скрипт Python из своего кода django, чтобы протестировать палочку с pdf-файлами, и он дает ту же ошибку. Я также проверил, находится ли Ghostscript в пути, и распечатал результаты делегатов convert -list.

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()

Вывод этой программы следующий. У него такая же ошибка отсутствующих делегатов. Та же ошибка возникает и с файлами tiff, но не с файлами jpg (первый тестовый файл — это jpg, и код обработал файл и создал миниатюру). Программа также распечатывает версию GS 9.10, доступную из программы, и распечатывает найденные ею делегаты, включая pdf-файлы:

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()

Может быть, этот простой код на Python поможет кому-то дать мне направление для решения этой проблемы. Однако я начинаю подозревать, что в wand есть ошибка, когда вместо имен файлов используются массивы байтов.

Спасибо!

Отметка


person user1045680    schedule 13.11.2017    source источник
comment
Я не очень хорошо знаком с Wand. Но часто с другими интерфейсами Ghostscript должен быть в PATH, используемом этим интерфейсом. Это часто происходит, например, с PHP Imagick. Так что убедитесь, что у вас есть этот набор. В качестве альтернативы вы можете отредактировать файл delegates.xml для PS и указать полный путь к Ghostscript. Обратите внимание, что ваша команда командной строки на самом деле не имеет правильного синтаксиса, хотя IM 6 довольно снисходителен. Вы должны прочитать ввод перед другими командами. Должно быть правильно convert Lucy.pdf[0] -thumbnail x300 -background white -alpha remove output_thumbnail.jpg. Какова была ваша команда Палочки?   -  person fmw42    schedule 14.11.2017
comment
Команда wand находится в первой строке трассировки, pages = Image(blob = b). Кроме того, на моем компьютере есть только один файл delegates.xml, и в нем есть все записи в формате pdf, ps и т. д. gs также находится по пути в /usr/bin. Я также проверил простую программу на Python, чтобы протестировать gs.   -  person user1045680    schedule 14.11.2017


Ответы (1)


В установленном файле ImageMagick delegates.xml вы найдете:

  <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;"/>

Там, где он имеет command="&quot;gs&quot;, измените его, чтобы указать полный путь к gs вместо gs; то есть command="&quot;path2/gs&quot;

Убедитесь, что вы изменили это в установленном файле, а не в каталоге загрузки ImageMagick. Перезагрузитесь и посмотрите, поможет ли это.

Извините, это мое единственное предложение. И снова я не очень знаком с Wand. Извиняюсь, если не поможет.

P.S. ImageMagick находится в /usr/bin или /usr/local/bin. Если последнее, это также в вашей переменной окружения PATH. Извините, если это очевидно.

person fmw42    schedule 14.11.2017
comment
Я не думаю, что это проблема пути gs, поскольку приведенная выше программа показывает, что программа может получить доступ к gs. Программа выше также показывает, что она может получить доступ ко всем делегатам ImageMagick для pdf. Я думаю, что это ошибка в палочке. Спасибо! - person user1045680; 15.11.2017
comment
Возможно, вы правы, поскольку я ничего не знаю об использовании Wand. Но вы получаете следующее сообщение об ошибке no decode delegate for this image format, что обычно означает, что он не может найти нужного делегата. Я предполагаю, что он не может найти Ghostscript из Wand, хотя может напрямую из ImageMagick. Именно поэтому я предложил попробовать указать полный путь к Ghostscript в файле delegates.xml. - person fmw42; 15.11.2017
comment
Если вы посмотрите на мой последний тестовый прогон, то увидите, что программа может найти GS, потому что выводит правильную версию (9.10). Тестовая программа также распечатывает всех делегатов, которые она может найти, включая pdf. Я также запустил ту же программу, но Wand считывал те же файлы с диска, а не передавал их в виде двоичных двоичных объектов, и все изображения обрабатывались должным образом. Итак, теперь я более уверен, что при чтении двоичных данных есть ошибка в wand, а не при чтении файла с локального диска. Спасибо за ваши комментарии! - person user1045680; 16.11.2017