sorl-thumbnail с ошибкой преобразования pdf / изображения серверной части graphicsmagick в Windows7

Я пытаюсь настроить приложение django sorl-thumbnail для предоставления эскизов pdf-файлов для веб-сайта, работающего на Windows Server 2008 R2 с веб-сервером Appache.

У меня был функционал sorl-thumbnail с бэкэндом PIL для создания миниатюр изображений jpeg, который работал нормально.

Поскольку PIL не может читать pdf-файлы, я хотел переключиться на бэкэнд graphicsmagick. Я установил и протестировал комбинацию graphicsmagick / ghostscript. Из командной строки

gm convert foo.pdf -resize 400x400 bar.jpg

генерирует ожидаемую миниатюру в формате jpg. Он также работает для создания эскизов из jpg в jpg.

Однако при вызове из sorl-thumbnail ghostscript дает сбой. Из оболочки django python (оболочка python manage.py) я использую команду низкого уровня, описанную в sorl docs и передайте экземпляр FieldFile (ff), указывающий на foo.pdf, и получите следующую ошибку:

In [8]: im = get_thumbnail(ff, '400x400', quality=95)
**** Warning: stream operator isn't terminated by valid EOL.
**** Warning: stream Length incorrect.
**** Warning:  An error occurred while reading an XREF table.
**** The file has been damaged.  This may have been caused
**** by a problem while converting or transfering the file.
**** Ghostscript will attempt to recover the data.
**** Error:  Trailer is not found.
GPL Ghostscript 9.07: Unrecoverable error, exit code 1

Обратите внимание, что ff указывает на тот же файл, который отлично конвертируется при использовании gm convert из командной строки.

Я также пробовал передать экземпляр ImageFieldFile (iff) и получил следующую ошибку:

In [5]: im = get_thumbnail(iff, '400x400', quality=95)
identify.exe: Corrupt JPEG data: 1 extraneous bytes before marker 0xdb `c:\users\thin\appdata\local\temp\tmpxs7m5p' @ warning/jpeg.c/JPEGWarningHandler/348.
identify.exe: Corrupt JPEG data: 1 extraneous bytes before marker 0xc4 `c:\users\thin\appdata\local\temp\tmpxs7m5p' @ warning/jpeg.c/JPEGWarningHandler/348.
identify.exe: Corrupt JPEG data: 1 extraneous bytes before marker 0xda `c:\users\thin\appdata\local\temp\tmpxs7m5p' @ warning/jpeg.c/JPEGWarningHandler/348.
Invalid Parameter - -auto-orient

Изменив настройки sorl, чтобы использовать бэкэнд PIL по умолчанию, и повторив команду для преобразования jpg в jpg, эскизное изображение создается без ошибок / предупреждений и доступно через кеш.

Похоже, что sorl копирует исходный файл во временный файл, прежде чем передать его в gm - и что проблема возникает в этой операции копирования.

Я нашел то, что, по моему мнению, является операцией копирования в исходных текстах строк 47-55 sorl_thumbnail-11.12-py2.7.egg \ sorl \ thumbnail \ motors \ convert_engine.py:

class Engine(EngineBase):

    ...

    def get_image(self, source):
        """
        Returns the backend image objects from a ImageFile instance
        """
        handle, tmp = mkstemp()
        with open(tmp, 'w') as fp:
            fp.write(source.read())
        os.close(handle)
        return {'source': tmp, 'options': SortedDict(), 'size': None}

Не в этом ли проблема - я этого не вижу!

Мы будем очень благодарны за любые предложения о том, как решить эту проблему! Я использую django 1.4, sorl-thumbnail 11.12 с memcached и ghostscript 9.07.


person thin    schedule 04.03.2013    source источник


Ответы (1)


После некоторых проб и ошибок я обнаружил, что проблему можно решить, изменив режим записи с 'w' на 'wb', чтобы исходники sorl_thumbnail-11.12-py2.7.egg \ sorl \ thumbnail \otors \ convert_engine Строки 47-55 .py теперь читаются:

class Engine(EngineBase):

    ...

    def get_image(self, source):
        """
        Returns the backend image objects from a ImageFile instance
        """
        handle, tmp = mkstemp()
        with open(tmp, 'wb') as fp:
            fp.write(source.read())
        os.close(handle)
        return {'source': tmp, 'options': SortedDict(), 'size': None}

Я полагаю, что в файле convert_engine.py есть еще два места, где следует сделать такое же изменение. После этого команда gm convert смогла обработать файл.

Однако, поскольку мои PDF-файлы представляют собой довольно большие многостраничные PDF-файлы, я столкнулся с другими проблемами, наиболее важной из которых является то, что метод get_image создает полную копию файла до создания эскиза. Таким образом, с размером файлов около 50 Мбайт это оказывается очень медленным процессом, и, наконец, я решил обойти sorl и вызвать gm напрямую. Затем эскиз сохраняется в стандартном ImageField. Не так элегантно, но намного быстрее.

person thin    schedule 08.03.2013