ImageMagick不再在AWS Lambda中转换pdf [英] ImageMagick not converting pdfs anymore in AWS Lambda

查看:175
本文介绍了ImageMagick不再在AWS Lambda中转换pdf的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去的18个月中,我已经在S3对象上运行了一个AWS Lambda函数,它在大约一个月前进行了一次小更新后就死了.我已经还原了它,但是还是坏了.我一直在研究使用ImageMagick进行pdf的最基本转换,但是没有运气,所以我认为AWS已更新了某些内容并导致pdf模块被删除或停止工作.

我只完成了我在Node.js 8.10的核心代码中基本完成的基本功能:

gm(response.Body).setFormat("png").stream((err, stdout,stderr) => {
  if (err) {
    console.log('broken');
  }
  const chunks = [];
  stdout.on('data', (chunk) => {
    chunks.push(chunk);
  });
  stdout.on('end', () => {
    console.log('gm done!');
  });
  stderr.on('data', (data) => {
    console.log('std error data ' + data);
  })
});

错误响应:

std错误数据转换:无法加载模块`/usr/lib64/ImageMagick-6.7.8/modules-Q16/coders/pdf.la':找不到文件

我还尝试过使用Node.js 10.x,并使用可通过aws无服务器应用程序存储库获得的ImageMagick层.在相同的代码上尝试生成此错误

std错误数据转换:FailedToExecuteCommand`'gs'-sstdout =%stderr -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap = 500000000 -dAlignToPixels = 0 -dGridFitTT = 2'-sDEVICE = pngalpha'-dTextAlphaBits = 4 -dGraphicsAlphaBits = 4'-r72x72''-sOutputFile =/tmp/magick-22TOeBgB4WrfoN%d''-f/tmp/magick-22KvuEBeuJuyq3''-f/tmp/magick-22dj24vSktMXsj''(1)@错误/pdf. c/InvokePDFDelegate/292

在这两种情况下,当在图像文件上运行时,该功能均可以正常工作.

基于此,我认为aws 8.10 ImageMagick和10的图层都缺少pdf模块,但是我不确定如何添加它或为什么首先将其删除.解决此功能的最佳方法是什么?

编辑

所以我已经下载了 https://github.com/serverlesspub/imagemagick-aws -lambda-2 并手动构建该库,将其上传到Lambda并成功地作为图层运行,但是它不包含GhostScript,它是一个可选库.我试图将其添加到Makefile_ImageMagick中,该Makefile_ImageMagick构建并在结果中具有对Ghostscript的一些引用,但是运行它不能解决PDF问题(图像仍然有效).将GhostScript可选库添加到Make文件中的最佳方法是什么?

解决方案

虽然其他答案有助于实现可行的解决方案,但仍有很多工作要做,所以下面是我设法解决此问题的方法,特别是针对NodeJS的解决方法. /p>

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

压缩bin目录并将其作为图层上传到Lambda.

添加 https://github.com/sina-masnadi/node-gs 到您的NodeJS模块.您可以将它们作为项目的一部分进行上传,也可以将我作为层进行上传(连同所有其他必需项一起进行).

添加 https://github.com/serverlesspub/imagemagick-aws-lambda-2 作为图层.最好的方法是在Lambda中创建一个新功能,选择浏览无服务器应用程序存储库,搜索"ImageMagick",然后选择"image-magick-lambda-layer"(您也可以构建它并将其作为图层上传) .

将三层添加到您的函数中,我已经按此顺序完成了

  1. GhostScript
  2. ImageMagick
  3. NodeJS模块

将appPath添加到ImageMagick和GhostScript的require语句中:

var gm = require("gm").subClass({imageMagick: true, appPath: '/opt/bin/'});
var gs = require('gs');

矿井位于异步瀑布中,因此在我之前的处理功能之前,我添加了此功能以将其转换为png(如果还没有图像的话):

  function convertIfPdf(response, next) {
    if (fileType == "pdf") {
      fs.writeFile("/tmp/temp.pdf", response.Body, function(err) {
        if (!err) {
          gs().batch().nopause().executablePath('/opt/bin/./gs').device('png16m').input("/tmp/temp.pdf").output('/tmp/temp.png').exec(function (err, stdout, stderr){
            if (!err && !stderr) {
              var data = fs.readFileSync('/tmp/temp.png');
              next(null, data);
            } else {
              console.log(err);
              console.log(stderr);
            }
          });
        }
      });
    } else {
      next(null, response.Body);
    }
  }

从那时起,您可以执行以前在ImageMagick中所做的相同格式的操作.可能有更好的方法来进行pdf转换,但是除非使用文件,否则我在GS库中遇到问题.如果有更好的方法,请告诉我.

如果在加载库时遇到问题,请确保路径正确,这取决于您将其压缩的方式.

I've had a AWS Lambda function running on S3 objects for the last 18 months and it died around a month ago after a minor update. I've reverted it but it's still broken. I've looked into doing the most basic conversion of pdf using ImageMagick with no luck so I think AWS has updated something and caused the pdf module to either be removed or stop working.

I've done just the basic function I was basically doing in my core code in Node.js 8.10:

gm(response.Body).setFormat("png").stream((err, stdout,stderr) => {
  if (err) {
    console.log('broken');
  }
  const chunks = [];
  stdout.on('data', (chunk) => {
    chunks.push(chunk);
  });
  stdout.on('end', () => {
    console.log('gm done!');
  });
  stderr.on('data', (data) => {
    console.log('std error data ' + data);
  })
});

with the error response:

std error dataconvert: unable to load module `/usr/lib64/ImageMagick-6.7.8/modules-Q16/coders/pdf.la': file not found

I've also tried moving to Node.js 10.x and using the ImageMagick layer that's available through the aws serverless app repository. Trying this on the same code generates this error

std error data convert: FailedToExecuteCommand `'gs' -sstdout=%stderr -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 '-sDEVICE=pngalpha' -dTextAlphaBits=4 -dGraphicsAlphaBits=4 '-r72x72' '-sOutputFile=/tmp/magick-22TOeBgB4WrfoN%d' '-f/tmp/magick-22KvuEBeuJuyq3' '-f/tmp/magick-22dj24vSktMXsj'' (1) @ error/pdf.c/InvokePDFDelegate/292

In both cases the function works correctly when running on an image file instead.

Based on this I think both the aws 8.10 ImageMagick and the layer for 10 are missing the pdf module but I'm unsure how to add it or why it was removed in the first place. Whats the best way to fix this function that was working?

EDIT

So I've downloaded https://github.com/serverlesspub/imagemagick-aws-lambda-2 and built the library manually, uploaded it to Lambda and got it successfully working as a layer however it doesn't include GhostScript of which it is an optional library. I've tried to add it to Makefile_ImageMagick which builds and has some references to Ghostscript in the result but running it doesn't fix the PDF issue (images still work). Whats the best way to add the GhostScript optional library to the Make file?

解决方案

While the other answers helped there was still a lot of work to get to a workable solution so below is how I managed to fix this, specifically for NodeJS.

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

zip up the bin directory and upload it as a layer into Lambda.

Add https://github.com/sina-masnadi/node-gs to your NodeJS modules. You can either upload them as part of your project or the way I did it as a layer (along with all your other required ones).

Add https://github.com/serverlesspub/imagemagick-aws-lambda-2 as a layer. Best way to do this is to create a new function in Lambda, Select Browse serverless app repository, search for "ImageMagick" and select "image-magick-lambda-layer" (You can also build it and upload it as a layer too).

Add the three layers to your function, I've done it in this order

  1. GhostScript
  2. ImageMagick
  3. NodeJS modules

Add the appPath to the require statement for ImageMagick and GhostScript:

var gm = require("gm").subClass({imageMagick: true, appPath: '/opt/bin/'});
var gs = require('gs');

Mine was in an async waterfall so before my previous processing function I added this function to convert to a png if wasn't an image already:

  function convertIfPdf(response, next) {
    if (fileType == "pdf") {
      fs.writeFile("/tmp/temp.pdf", response.Body, function(err) {
        if (!err) {
          gs().batch().nopause().executablePath('/opt/bin/./gs').device('png16m').input("/tmp/temp.pdf").output('/tmp/temp.png').exec(function (err, stdout, stderr){
            if (!err && !stderr) {
              var data = fs.readFileSync('/tmp/temp.png');
              next(null, data);
            } else {
              console.log(err);
              console.log(stderr);
            }
          });
        }
      });
    } else {
      next(null, response.Body);
    }
  }

From then on you can do what you were previously doing in ImageMagick as it's in the same format. There may be better ways to do the pdf conversion but I was having issues with the GS library unless working with files. If there are better ways let me know.

If you are having issues loading the libraries make sure the path is correct, it is dependent on how you zipped it up.

这篇关于ImageMagick不再在AWS Lambda中转换pdf的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆