我正在开发应用程序,用户可以在其中上传一些 pdf 格式的图纸。上传的文件存储在S3上。上传后,文件必须转换为图像。为此,我创建了 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
/tmp/sourceFile.pdf':没有这样的
文件或目录@ error/pdf.c/ReadPDFImage/678。转换:无图像
定义`/tmp/targetFile.png' @
错误/convert.c/ConvertImageCommand/3046。 ] 被杀:假,代码:1,
信号:空,cmd:'/bin/sh -c 转换/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(用或
不使用 imagemagick)来修复或忽略错误,就像它所做的那样
我当地的环境?
- 如果旧版本有问题,是否可以构建ghostscript
从源代码创建nodejs模块,然后使用该版本
Ghostscript 而不是安装的那个?
- 有没有更简单的方法将 pdf 转换为图像而不使用
imagemagick 和 Ghostscript ?
UPDATElambda代码的相关部分:
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...
}
});
});