web-dev-qa-db-fra.com

ImageMagick ne convertit plus les fichiers PDF dans AWS Lambda

J'ai eu une fonction AWS Lambda exécutée sur des objets S3 au cours des 18 derniers mois et elle est morte il y a environ un mois après une mise à jour mineure. Je l'ai rétabli mais il est toujours cassé. J'ai cherché à faire la conversion la plus basique de pdf en utilisant ImageMagick sans chance, donc je pense qu'AWS a mis à jour quelque chose et a causé la suppression ou l'arrêt du module pdf.

J'ai fait juste la fonction de base que je faisais essentiellement dans mon code principal dans 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);
  })
});

avec la réponse d'erreur:

erreur std dataconvert: impossible de charger le module `/usr/lib64/ImageMagick-6.7.8/modules-Q16/coders/pdf.la ': fichier introuvable

J'ai également essayé de passer à Node.js 10.x et d'utiliser la couche ImageMagick disponible via le référentiel d'applications sans serveur aws. Essayer ceci sur le même code génère cette erreur

conversion des données d'erreur std: FailedToExecuteCommand `` gs '-sstdout =% stderr -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap = 500000000 -dAlignToPixels = 0 -dGridFitTT = 2' -spAlBal 4 '-r72x72' '-sOutputFile =/tmp/magick-22TOeBgB4WrfoN% d' '-f/tmp/magick-22KvuEBeuJuyq3' '-f/tmp/magick-22dj24vSktMXsj' '(1) @ error/pdf.cegatePDF/292

Dans les deux cas, la fonction fonctionne correctement lors de l'exécution sur un fichier image à la place.

Sur cette base, je pense que le module pdf aws 8.10 ImageMagick et le calque 10 ne contiennent pas le module pdf, mais je ne sais pas comment l'ajouter ni pourquoi il a été supprimé en premier lieu. Quelle est la meilleure façon de corriger cette fonction qui fonctionnait?

[~ # ~] modifier [~ # ~]

J'ai donc téléchargé https://github.com/serverlesspub/imagemagick-aws-lambda-2 et construit la bibliothèque manuellement, je l'ai téléchargée sur Lambda et je l'ai fait fonctionner avec succès en tant que couche comme elle ne le fait pas n'inclut pas GhostScript dont il s'agit d'une bibliothèque facultative. J'ai essayé de l'ajouter à Makefile_ImageMagick qui construit et contient des références à Ghostscript dans le résultat mais en l'exécutant ne résout pas le problème PDF (les images fonctionnent toujours). Quel est le meilleur moyen d'ajouter la bibliothèque facultative GhostScript à la Créer un fichier?

10
Rudiger

Bien que les autres réponses aient aidé, il y avait encore beaucoup de travail à faire pour trouver une solution viable, alors voici comment j'ai réussi à résoudre ce problème, en particulier pour NodeJS.

Télécharger: https://github.com/sina-masnadi/lambda-ghostscript

Compressez le répertoire bin et téléchargez-le en tant que couche dans Lambda.

Ajoutez https://github.com/sina-masnadi/node-gs à vos modules NodeJS. Vous pouvez les télécharger dans le cadre de votre projet ou comme je l'ai fait en tant que couche (avec tous les autres requis).

Ajoutez https://github.com/serverlesspub/imagemagick-aws-lambda-2 en tant que couche. La meilleure façon de le faire est de créer une nouvelle fonction dans Lambda, sélectionnez Parcourir le référentiel d'applications sans serveur, recherchez "ImageMagick" et sélectionnez "image-magick-lambda-layer" (Vous pouvez également le créer et le télécharger en tant que calque également) .

Ajoutez les trois couches à votre fonction, je l'ai fait dans cet ordre

  1. GhostScript
  2. ImageMagick
  3. Modules NodeJS

Ajoutez l'appPath à l'instruction require pour ImageMagick et GhostScript:

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

Le mien était dans une cascade asynchrone donc avant ma fonction de traitement précédente, j'ai ajouté cette fonction pour convertir en png si ce n'était pas déjà une image:

  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);
    }
  }

À partir de là, vous pouvez faire ce que vous faisiez auparavant dans ImageMagick car il est dans le même format. Il y a peut-être de meilleures façons de faire la conversion pdf, mais j'avais des problèmes avec la bibliothèque GS à moins de travailler avec des fichiers. S'il y a de meilleures façons, faites le moi savoir.

Si vous rencontrez des problèmes lors du chargement des bibliothèques, assurez-vous que le chemin est correct, cela dépend de la façon dont vous l'avez compressé.

13
Rudiger

J'ai eu le même problème. Deux services cloud traitant des milliers de pages PDF par jour échouant en raison de l'erreur pdf.la introuvable.

La solution consistait à passer d'Image Magick à GhostScript pour convertir des PDF en PNG, puis d'utiliser ImageMagick avec des PNG (si nécessaire). De cette façon, la messagerie instantanée n'a jamais à gérer les fichiers PDF et n'a pas besoin du fichier pdf.la.

Pour utiliser GhostScript sur AWS Lambda, téléchargez simplement le binaire gs dans le fichier Zip de la fonction.

3
José Augusto Paiva

J'ai eu le problème où ghostscript n'était plus trouvé.

Auparavant, j'avais référencé ghostscript via:

var gs = '/usr/bin/gs';

Depuis qu'AWS lambda a cessé de fournir ce package, je suis allé et l'ai inclus directement dans ma fonction lambda qui fonctionnait pour moi. Je viens de télécharger les fichiers depuis https://github.com/sina-masnadi/lambda-ghostscript et je les ai placés dans un dossier appelé 'ghostscript' Puis je les ai référencés ainsi:

var path = require('path')
var gs = path.join(__dirname,"ghostscript","bin","gs")
1
Raymond Nguyen

Vous pouvez ajouter une couche à votre fonction lambda pour la faire fonctionner à nouveau jusqu'au 22/07/2019. L'ARN de la couche que vous devez ajouter est le suivant: arn: aws: lambda ::: awslayer: AmazonLinux1703

La procédure est décrite à coming-updates-to-the-aws-lambda-execution-environment

Toute solution à long terme serait merveilleuse.

1
Nicolas Oste