AWS Lambda函数 – 将PDF转换为图像

我正在开发应用程序,用户可以上传一些PDF格式的图纸。 上传的文件存储在S3上。 上传后,文件必须转换为图像。 为此,我创build了lambda函数,它将文件从S3下载到lambda执行环境中的/ tmp文件夹,然后从imagemagick调用“convert”命令。

convert sourceFile.pdf targetFile.png

Lambda运行时环境是nodejs 4.3。 内存设置为128MB,超时30秒。

现在的问题是,有些文件转换成功,而其他人失败,出现以下错误:

{[错误:命令失败:/ bin / sh -c转换/tmp/sourceFile.pdf /tmp/targetFile.png转换: %s' (%d) "gs" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sDEVICE=pngalpha" -dTextAlphaBits=4 -dGraphicsAlphaBits=4 "-r72x72" "-sOutputFile=/tmp/magick-QRH6nVLV--0000001" "-f/tmp/magick-B610L5uo" "-f/tmp/magick-tIe1MjeR" @ error/utility.c/SystemCommand/1890. convert: Postscript delegate failed %s' (%d) "gs" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sDEVICE=pngalpha" -dTextAlphaBits=4 -dGraphicsAlphaBits=4 "-r72x72" "-sOutputFile=/tmp/magick-QRH6nVLV--0000001" "-f/tmp/magick-B610L5uo" "-f/tmp/magick-tIe1MjeR" @ error/utility.c/SystemCommand/1890. convert: Postscript delegate failed /tmp/sourceFile.pdf':没有这样的文件或目录@ error / pdf.c / ReadPDFImage / 678。 转换:没有图像定义`/tmp/targetFile.png'@ error / convert.c / ConvertImageCommand / 3046。 ] killed:false,code:1,signal:null,cmd:'/ bin / sh -c convert /tmp/sourceFile.pdf /tmp/targetFile.png'}

起初,我不明白为什么发生这种情况,然后我尝试用本命令转换本地Ubuntu机器上的有问题的文件。 这是terminal的输出:

**** Warning: considering '0000000000 XXXXX n' as a free entry. **** This file had errors that were repaired or ignored. **** The file was produced by: **** >>>> Mac OS X 10.10.5 Quartz PDFContext <<<< **** Please notify the author of the software that produced this **** file that it does not conform to Adobe's published PDF **** specification.

所以这个消息非常清楚,但是文件无论如何都被转换成了png。 如果我尝试convert source.pdf target.pdf ,然后convert target.pdf image.png ,则文件将被修复并转换而不会出现任何错误。 这不适用于lambda。

既然同一个东西在一个环境下工作,但是在另一个环境下工作,我最好的猜测就是Ghostscript的版本是问题。 在AMI上安装的版本是8.70。 在我的本地机器上Ghostsript版本是9.18。

我的问题是:

  • ghostscript问题的版本是? 这是一个老版本的ghostscript的错误? 如果没有,我怎么能告诉ghostscript(无论是否使用imagemagick)来修复或忽略它在我的本地环境中的错误?
  • 如果旧版本有问题,是否可以从源代码构buildghostscript,创buildnodejs模块,然后使用该版本的ghostscript代替安装的版本?
  • 有没有更容易的方法来转换PDF格式图像,而不使用imagemagick和ghostscript?

更新 lambda代码的相关部分:

 var exec = require('child_process').exec; var AWS = require('aws-sdk'); var fs = require('fs'); ... var localSourceFile = '/tmp/sourceFile.pdf'; var localTargetFile = '/tmp/targetFile.png'; var writeStream = fs.createWriteStream(localSourceFile); writeStream.write(body); writeStream.end(); writeStream.on('error', function (err) { console.log("Error writing data from s3 to tmp folder."); context.fail(err); }); writeStream.on('finish', function () { var cmd = 'convert ' + localSourceFile + ' ' + localTargetFile; exec(cmd, function (err, stdout, stderr ) { if (err) { console.log("Error executing convert command."); context.fail(err); } if (stderr) { console.log("Command executed successfully but returned error."); context.fail(stderr); }else{ //file converted successfully - do something... } }); }); 

您可以在以下存储库中findGhostscript for Lambda的编译版本。 您应该将这些文件添加到作为AWS Lambda源代码上传的zip文件中。

https://github.com/sina-masnadi/lambda-ghostscript

这是一个调用Ghostscript函数的npm包:

https://github.com/sina-masnadi/node-gs

在将已编译的Ghostscript文件复制到项目中并添加npm包之后,可以使用executablePath('path to ghostscript')函数将程序包指向之前添加的已编译的Ghostscript文件。

它几乎可以肯定是Ghostscript的老版本的错误,或者可能是限制。

许多PDF制作者创build不符合规范的PDF文件,然而在Adobe Acrobat中不会投诉。 Ghostscript也是这样做的,但显然我们不知道Acrobat会允许什么,所以我们一直在追求这个模糊的目标。 (FWIW警告是一个合法的不合规格的PDF文件)。

除了replace旧版本之外,你无能为力。

是的,你可以从源代码构buildGhostscript,我不知道nodejs模块,不知道为什么这是相关的。

还有许多其他应用程序将呈现PDF文件,MuPDF是我所知道的另一个应用程序。 而且,当然,您可以直接使用Ghostscript而不使用ImageMagick。 当然,如果你可以加载另一个应用程序,那么你应该只需要replace你的Ghostscript安装。