几次成功后,使用 wand 将图像转换为 pdf 失败
Using wand to convert image to pdf fails after a few successful results
我的应用程序运行了几次,然后在每个 pdf 上都出现错误。这是我收到的错误:
Exception TypeError: TypeError("object of type 'NoneType' has no len()",) in <bound method Image.__del__ of <wand.image.Image: (empty)>> ignored
这是我使用的函数:
def read_pdf(file):
pre, ext = os.path.splitext(file)
filename = pre + '.png'
with Image(filename=file, resolution=200) as pdf:
amount_of_pages = len(pdf.sequence)
image = Image(
width=pdf.width,
height=pdf.height * amount_of_pages
)
for i in range(0, amount_of_pages):
image.composite(
pdf.sequence[i],
top=pdf.height * i,
left=0
)
image.compression_quality = 100
image.save(filename=filename)
logging.info('Opened and saved pdf to image: \'' + file + '\'.')
return filename
此函数可以正确地将 pdf 文件转换为图像,但经过两到三次后,每次都会崩溃并抛出该异常。如果我重新启动 python 脚本,它会再次运行几次。
错误是由系统运行资源不足引起的。 Wand 调用 ImageMagick 库;反过来,将解码工作传递给 Ghostscript 委托。 Ghostscript 非常稳定,但确实会占用大量资源,并且在 运行 并行时不开心(我的意见)。
Any help?
- 尝试构建一个允许在 PDF 转换之间干净关闭的解决方案。就像队列工作者或 subprocess 脚本。最小的资源泄漏可能会迅速失控。
- 避免调用
wand.image.Image.sequance
。已经报告了一些已知的内存泄漏问题。尽管许多问题已得到修复,但 PDF 任务似乎仍然存在问题。
从发布的代码来看,您似乎只是用给定 PDF 的所有页面创建了一个高大的图像。我建议直接移植MagickAppendImages
。
import ctypes
from wand.image import Image
from wand.api import library
# Map C-API to python
library.MagickAppendImages.argtypes = (ctypes.c_void_p, ctypes.c_bool)
library.MagickAppendImages.restype = ctypes.c_void_p
with Image(filename='source.pdf') as pdf:
# Reset image stack
library.MagickResetIterator(pdf.wand)
# Append all pages into one new image
new_ptr = library.MagickAppendImages(pdf.wand, True)
library.MagickWriteImage(new_ptr, b'output.png')
library.DestroyMagickWand(new_ptr)
看来我创建了一个新的图像,并没有破坏它。这填满了内存。
我只需要使用 with new Image(...) as img
而不是 img = new Image(...)
。
我的应用程序运行了几次,然后在每个 pdf 上都出现错误。这是我收到的错误:
Exception TypeError: TypeError("object of type 'NoneType' has no len()",) in <bound method Image.__del__ of <wand.image.Image: (empty)>> ignored
这是我使用的函数:
def read_pdf(file):
pre, ext = os.path.splitext(file)
filename = pre + '.png'
with Image(filename=file, resolution=200) as pdf:
amount_of_pages = len(pdf.sequence)
image = Image(
width=pdf.width,
height=pdf.height * amount_of_pages
)
for i in range(0, amount_of_pages):
image.composite(
pdf.sequence[i],
top=pdf.height * i,
left=0
)
image.compression_quality = 100
image.save(filename=filename)
logging.info('Opened and saved pdf to image: \'' + file + '\'.')
return filename
此函数可以正确地将 pdf 文件转换为图像,但经过两到三次后,每次都会崩溃并抛出该异常。如果我重新启动 python 脚本,它会再次运行几次。
错误是由系统运行资源不足引起的。 Wand 调用 ImageMagick 库;反过来,将解码工作传递给 Ghostscript 委托。 Ghostscript 非常稳定,但确实会占用大量资源,并且在 运行 并行时不开心(我的意见)。
Any help?
- 尝试构建一个允许在 PDF 转换之间干净关闭的解决方案。就像队列工作者或 subprocess 脚本。最小的资源泄漏可能会迅速失控。
- 避免调用
wand.image.Image.sequance
。已经报告了一些已知的内存泄漏问题。尽管许多问题已得到修复,但 PDF 任务似乎仍然存在问题。
从发布的代码来看,您似乎只是用给定 PDF 的所有页面创建了一个高大的图像。我建议直接移植MagickAppendImages
。
import ctypes
from wand.image import Image
from wand.api import library
# Map C-API to python
library.MagickAppendImages.argtypes = (ctypes.c_void_p, ctypes.c_bool)
library.MagickAppendImages.restype = ctypes.c_void_p
with Image(filename='source.pdf') as pdf:
# Reset image stack
library.MagickResetIterator(pdf.wand)
# Append all pages into one new image
new_ptr = library.MagickAppendImages(pdf.wand, True)
library.MagickWriteImage(new_ptr, b'output.png')
library.DestroyMagickWand(new_ptr)
看来我创建了一个新的图像,并没有破坏它。这填满了内存。
我只需要使用 with new Image(...) as img
而不是 img = new Image(...)
。