node.js - AWS Lambda 函数 - 将 PDF 转换为图像

标签 node.js imagemagick ghostscript aws-lambda

我正在开发应用程序,用户可以在其中上传一些 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/

相关文章:

svg - 将一堆图像从 svg 转换为 png

pdf - 如何从 PDF 中提取嵌入字体作为有效字体文件?

linux - 我们如何在 Linux 上合并 pdf 文件中的 2 页

mysql - Node.js 应用程序部署在谷歌云上,与不同服务器上的远程 mysql 连接。

node.js - Socketcluster自定义错误

javascript - 如何在 Express.js 中使用 Less?

node.js - Google 翻译 api 响应不是目标语言

java - Process Builder 无法在 Windows 上运行

linux - 如何从 shell 脚本中的命令输出中获取字符串模式?

php - Imagemagick Crop 命令没有给出完美的结果