无法在Google Cloud Function中使用Wand / ImageMagick加载PDF

时间:2019-04-02 22:34:38

标签: python-3.x pdf imagemagick google-cloud-functions wand

试图从本地文件系统加载PDF并收到“未授权”错误。

  

在读取self.raise_exception()文件的“ /env/local/lib/python3.7/site-packages/wand/image.py”行4896中,文件“ /env/local/lib/python3.7” /site-packages/wand/resource.py“,第222行,在raise_exception中引发e wand.exceptions.PolicyError:未经授权的`/ tmp / tmp_iq12nws'@ error / constitute.c / ReadImage / 412

PDF文件已成功从GCS保存到本地“服务器”,但不会被Wand加载。将图像加载到OpenCV中不是问题,只是在尝试使用Wand / ImageMagick加载PDF时发生

下面是将PDF从GCS加载到本地文件系统到Wand / ImageMagick的代码

_, temp_local_filename = tempfile.mkstemp()
gcs_blob = STORAGE_CLIENT.bucket('XXXX').get_blob(results["storedLocation"])
gcs_blob.download_to_filename(temp_local_filename)
# load the pdf into a set of images using imagemagick
with(Image(filename=temp_local_filename, resolution=200)) as source:
    #run through pages and save images etc.

应该授权ImageMagick访问本地文件系统上的文件,以便它应加载文件而不会出现问题,而不是出现此“未授权”错误。

1 个答案:

答案 0 :(得分:1)

由于存在安全漏洞Ghostscript had,已禁用ImageMagick的PDF阅读功能。该问题是设计使然,直到存在ImageMagick团队的安全缓解措施。 ImageMagick再次启用PDF的Ghostscript处理,并且Google Cloud Functions更新为ImageMagick的新版本,并再次启用了PDF处理。

我找不到GCF中ImageMagick / Wand问题的修复程序,但作为将PDF转换为Google Cloud Functions中图像的一种解决方法,您可以使用此[ghostscript包装器] [2]直接请求将PDF转换为通过Ghostscript图像,并绕过ImageMagick / Wand。然后,您可以毫无问题地将PNG加载到ImageMagick或OpenCV中。

requirements.txt

google-cloud-storage
ghostscript==0.6

main.py

    # create a temp filename and save a local copy of pdf from GCS
    _, temp_local_filename = tempfile.mkstemp()
    gcs_blob = STORAGE_CLIENT.bucket('XXXX').get_blob(results["storedLocation"])
    gcs_blob.download_to_filename(temp_local_filename)
    # create a temp folder based on temp_local_filename
    temp_local_dir = tempfile.mkdtemp()
    # use ghostscript to export the pdf into pages as pngs in the temp dir
    args = [
        "pdf2png", # actual value doesn't matter
        "-dSAFER",
        "-sDEVICE=pngalpha",
        "-o", temp_local_dir+"page-%03d.png",
        "-r300", temp_local_filename
        ]
    # the above arguments have to be bytes, encode them
    encoding = locale.getpreferredencoding()
    args = [a.encode(encoding) for a in args]
    #run the request through ghostscript
    ghostscript.Ghostscript(*args)
    # read the files in the tmp dir and process the pngs individually
    for png_file_loc in glob.glob(temp_local_dir+"*.png"):
        # loop through the saved PNGs, load into OpenCV and do what you want
        cv_image = cv2.imread(png_file_loc, cv2.IMREAD_UNCHANGED)

希望这可以帮助面临相同问题的人。