我正在开发应用程序,用户可以在其中上传一些 pdf 格式的图纸。上传的文件存储在 S3 上。上传后,文件必须转换为图像。为此,我创建了 lambda 函数,该函数将文件从 S3 下载到 lambda 执行环境中的/tmp 文件夹,然后我从 imagemagick 调用“convert”命令。
convert sourceFile.pdf targetFile.png
Lambda 运行环境为 nodejs 4.3。内存设置为 128MB,超时 30 秒。
现在的问题是一些文件转换成功,而另一些文件转换失败并出现以下错误:
{ [Error: Command failed: /bin/sh -c convert /tmp/sourceFile.pdf /tmp/targetFile.png convert:
%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': No such file or directory @ error/pdf.c/ReadPDFImage/678. convert: no images defined `/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 机器上转换有问题的文件。这是终端的输出:
**** 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) 来修复或忽略错误,就像它在 我的本地环境?
- 如果旧版本有问题,是否可以构建ghostscript 从源代码,创建 nodejs 模块,然后使用该版本的 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...
}
});
});
最佳答案
您可以在以下存储库中找到适用于 Lambda 的 Ghostscript 编译版本。 您应该将这些文件添加到您要作为源代码上传到 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 文件早些。
关于node.js - AWS Lambda 函数 - 将 PDF 转换为图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39205035/