0

我正在尝试设置 sorl-thumbnail django 应用程序来为网站提供 pdf 文件的缩略图 - 在带有 Appache Web 服务器的 Windows Server 2008 R2 上运行。

我已经使用 PIL 后端的 sorl-thumbnail 功能来生成 jpeg 图像的缩略图 - 这工作正常。

由于 PIL 无法读取 pdf 文件,我想切换到 graphicsmagick 后端。我已经安装并测试了 graphicsmagick/ghostscript 组合。从命令行

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

生成预期的 jpg 缩略图。它也适用于 jpg 到 jpg 缩略图生成。

但是,当从 sorl-thumbnail 调用时,ghostscript 会崩溃。从 django python shell (python manage.py shell) 我使用sorl 文档中描述的低级命令并传入指向 foo.pdf 的 FieldFile 实例 (ff) 并得到以下错误:

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

请注意,从命令行使用 gm convert 时,ff 指向的文件可以正常转换。

我也尝试过传递 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 之前将其复制到临时文件中 - 问题出在此复制操作中。

我在 sorl_thumbnail-11.12-py2.7.egg\sorl\thumbnail\engines\convert_engine.py 第 47-55 行的源代码中发现了我认为是复制操作:

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。

4

1 回答 1

0

经过一番反复试验,我发现可以通过将写入模式从'w'更改为'wb'来解决问题,以便sorl_thumbnail-11.12-py2.7.egg\sorl\thumbnail\engines\convert_engine的来源.py 第 47-55 行现在为:

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 Mb,因此结果证明这是一个非常缓慢的过程,最后我选择绕过 sorl 并直接调用 gm。然后将缩略图存储在标准 ImageField 中。不是那么优雅,但要快得多。

于 2013-03-08T22:01:52.647 回答