Функция GS Firebase не может установить смещение? - PullRequest
0 голосов
/ 02 апреля 2020

Я использую функции Firebase, чтобы обрезать определенную область PDF и преобразовать их в изображение, используя ghostscript [Оболочка https://www.npmjs.com/package/node-gs и скомпилированную версию GS v9.2 "https://github.com/sina-masnadi/node-gs/tarball/master "]

и это код, который я использую:

const functions = require('firebase-functions');
const { Storage } = require('@google-cloud/storage');
const gcs = new Storage();
const spawn = require('child-process-promise').spawn;
const path = require('path');
const os = require('os');
const fs = require('fs');
var gs = require('gs');


const THUMB_MAX_HEIGHT = 200;
const THUMB_MAX_WIDTH = 200;
const THUMB_SUFFIX = '-thumb';

//This function triggers whenever any pdf is uploaded to the firebase storage
//and attempts to generate

exports.makePreviews = functions.storage.object().onFinalize(async (object, event) => {

  //Checking for pdf files
  if (!object.name.endsWith('.pdf')) return false;

  const filePath = object.name;

  //slicing name and path
  const splitFileName = object.name.split(".");
  console.log(splitFileName);
  const fileID = splitFileName;

  //creating temporary path strings for gcp file system
  const fileName = path.basename(filePath);
  const tempFilePath = path.join(os.tmpdir(), fileName);

  const newName1 = path.basename(filePath, '.pdf') + '01.jpeg';
  const tempNewPath1 = path.join(os.tmpdir(), newName1);

  const newName2 = path.basename(filePath, '.pdf') + '02.jpeg';
  const tempNewPath2 = path.join(os.tmpdir(), newName2);

  const thumbName = path.basename(filePath, '.pdf') + THUMB_SUFFIX + '.jpeg';
  const tempThumbPath = path.join(os.tmpdir(), thumbName);


  //downloading file from firebase storage
  const bucket = gcs.bucket(object.bucket);

  return bucket.file(filePath).download({
    destination: tempFilePath
  }).then(async () => {
    console.log('PDF downloaded locally to', tempFilePath);

    //generating two preview JPEGS
    await new Promise((resolve, reject) => {
      gs()
        .safer()
        .batch()
        .nopause()
        .option('-dTextAlphaBits=4')
        .option('-dGraphicsAlphaBits=4')
        .option('-dDEVICEWIDTHPOINTS=238')
        .option('-dDEVICEHEIGHTPOINTS=149.5')
        .option('-dFIXEDMEDIA')
        .res(600)
        .option('-dDownScaleFactor=2')
        .executablePath('gs')
        .device('jpeg')
        .output(tempNewPath2)
        .option('-c "<</PageOffset[-308.5 40]>> setpagedevice"')
        .option('-sPDFPassword=01011977')
        .input(tempFilePath)
        .exec((err, stdout, stderr) => {
          if (!err) {
            console.log('Part One Exceuted');
            bucket.upload(tempNewPath1, {
              destination: 'files/' + fileID + '.jpeg'
            }).then(() => {
              console.log('stdout', stdout);
              console.log('stderr', stderr);
            }).catch(err => {
              console.log(err);
            });
            resolve();
          } else {
            console.log('gs error:', err);
            reject(err);
          }
        });
    });

    await new Promise((resolve, reject) => {
      gs()
        .safer()
        .batch()
        .nopause()
        .option('-dTextAlphaBits=4')
        .option('-dGraphicsAlphaBits=4')
        .option('-dDEVICEWIDTHPOINTS=238')
        .option('-dDEVICEHEIGHTPOINTS=149.5')
        .option('-dFIXEDMEDIA')
        .res(600)
        .option('-dDownScaleFactor=2')
        .executablePath('gs')
        .device('jpeg')
        .output(tempNewPath2)
        .option('-c "<</PageOffset[-308.5 40]>> setpagedevice"')
        .option('-sPDFPassword=01011977')
        .input(tempFilePath)
        .exec((err, stdout, stderr) => {
          if (!err) {
            console.log('gs Part two excuted');
            bucket.upload(tempNewPath1, {
              destination: 'files/' + fileID + '-2.jpeg'
            }).then(() => {
              console.log('stdout', stdout);
              console.log('stderr', stderr);
            })
              .catch(err => {
                console.log(err);
              });
            resolve();
          } else {
            console.log('gs error:', err);
            reject(err);
          }
        });
    });

    //generating thumbnail from the first JPEG
    return spawn('convert', [tempNewPath1, '-thumbnail', `${THUMB_MAX_WIDTH}x${THUMB_MAX_HEIGHT}>`, tempThumbPath], {
      capture: ['stdout', 'stderr']
    });

  }).then(async () => {
    console.log('PNG created at', tempNewPath1 + 'and' + tempNewPath2);
    console.log('Thumbnail created at', tempThumbPath);

    //uploading the files back to firebase storage
    return bucket.upload(tempThumbPath, {
      destination: 'files/' + fileID + 'thumb.jpeg'
    });


  }).then(() => {
    //once the files have been uploaded delete the local temporary 
    //files to free up disk space.
    fs.unlinkSync(tempNewPath1);
    fs.unlinkSync(tempNewPath2);
    fs.unlinkSync(tempThumbPath);
    return fs.unlinkSync(tempFilePath);
  }).catch((err) => {
    console.log('exception:', err);
    return err;
  });
});

развертывание вышеуказанного кода, журнал:

[ 'PAN_01011977', 'pdf' ]

PDF downloaded locally to /tmp/PAN_01011977.pdf

gs command: -dSAFER,-dBATCH,-dNOPAUSE,-dTextAlphaBits=4,-dGraphicsAlphaBits=4,-dDEVICEWIDTHPOINTS=238,-dDEVICEHEIGHTPOINTS=149.5,-dFIXEDMEDIA,-r600,-dDownScaleFactor=2,-sDEVICE=jpeg,-sOutputFile=/tmp/PAN_0101197702.jpeg,-c "<</PageOffset[-308.5 40]>> setpagedevice",-sPDFPassword=01011977,/tmp/PAN_01011977.pdf

Part One Exceuted

gs command: -dSAFER,-dBATCH,-dNOPAUSE,-dTextAlphaBits=4,-dGraphicsAlphaBits=4,-dDEVICEWIDTHPOINTS=238,-dDEVICEHEIGHTPOINTS=149.5,-dFIXEDMEDIA,-r600,-dDownScaleFactor=2,-sDEVICE=jpeg,-sOutputFile=/tmp/PAN_0101197702.jpeg,-c "<</PageOffset[-308.5 40]>> setpagedevice",-sPDFPassword=01011977,/tmp/PAN_01011977.pdf

{ Error: ENOENT: no such file or directory, stat '/tmp/PAN_0101197701.jpeg'
  errno: -2,
  code: 'ENOENT',
  syscall: 'stat',
  path: '/tmp/PAN_0101197701.jpeg' }

gs Part two excuted

{ Error: ENOENT: no such file or directory, stat '/tmp/PAN_0101197701.jpeg'
  errno: -2,
  code: 'ENOENT',
  syscall: 'stat',
  path: '/tmp/PAN_0101197701.jpeg' }

и ошибка:

and the error log

exception: { ChildProcessError: `convert /tmp/PAN_0101197701.jpeg -thumbnail 200x200> /tmp/PAN_01011977-thumb.jpeg` failed with code 1
    at ChildProcess.<anonymous> (/srv/node_modules/child-process-promise/lib/index.js:132:23)
    at emitTwo (events.js:126:13)
    at ChildProcess.emit (events.js:214:7)
    at maybeClose (internal/child_process.js:915:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:209:5)
  name: 'ChildProcessError',
  code: 1,
  childProcess: 
   ChildProcess {
     domain: 
      Domain {
        domain: null,
        _events: [Object],
        _eventsCount: 1,
        _maxListeners: undefined,
        members: [Array] },
     _events: { error: [Function], close: [Function] },
     _eventsCount: 2,
     _maxListeners: undefined,
     _closesNeeded: 3,
     _closesGot: 3,
     connected: false,
     signalCode: null,
     exitCode: 1,
     killed: false,
     spawnfile: 'convert',
     _handle: null,
     spawnargs: 
      [ 'convert',
        '/tmp/PAN_0101197701.jpeg',
        '-thumbnail',
        '200x200>',
        '/tmp/PAN_01011977-thumb.jpeg' ],
     pid: 14,
     stdin: 
      Socket {
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: null,
        _readableState: [Object],
        readable: false,
        domain: [Object],
        _events: [Object],
        _eventsCount: 2,
        _maxListeners: undefined,
        _writableState: [Object],
        writable: false,
        allowHalfOpen: false,
        _bytesDispatched: 0,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: null,
        _server: null,
        _idleNext: null,
        _idlePrev: null,
        _idleTimeout: -1,
        [Symbol(asyncId)]: 4540,
        [Symbol(bytesRead)]: 0 },
     stdout: 
      Socket {
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: null,
        _readableState: [Object],
        readable: false,
        domain: [Object],
        _events: [Object],
        _eventsCount: 3,
        _maxListeners: undefined,
        _writableState: [Object],
        writable: false,
        allowHalfOpen: false,
        _bytesDispatched: 0,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: null,
        _server: null,
        _idleNext: null,
        _idlePrev: null,
        _idleTimeout: -1,
        write: [Function: writeAfterFIN],
        [Symbol(asyncId)]: 4541,
        [Symbol(bytesRead)]: 0 },
     stderr: 
      Socket {
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: null,
        _readableState: [Object],
        readable: false,
        domain: [Object],
        _events: [Object],
        _eventsCount: 3,
        _maxListeners: undefined,
        _writableState: [Object],
        writable: false,
        allowHalfOpen: false,
        _bytesDispatched: 0,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: null,
        _server: null,
        _idleNext: null,
        _idlePrev: null,
        _idleTimeout: -1,
        write: [Function: writeAfterFIN],
        [Symbol(asyncId)]: 4542,
        [Symbol(bytesRead)]: 232 },
     stdio: [ [Object], [Object], [Object] ] },
  stdout: '',
  stderr: 'convert-im6.q16: unable to open image `/tmp/PAN_0101197701.jpeg\': No such file or directory @ error/blob.c/OpenBlob/2701.\nconvert-im6.q16: no images defined `/tmp/PAN_01011977-thumb.jpeg\' @ error/convert.c/ConvertImageCommand/3258.\n' }

Error serializing return value: TypeError: Converting circular structure to JSON


Function execution took 9561 ms, finished with status: 'ok'

Проблема в том, что в gs используется опция ниже, эта функция работает, но она не обрезает pdf, просто преобразует изображение в полную страницу.

  //.option('-c "<</PageOffset [ -64.2 40 ]>> setpagedevice"')
  //.option('-c "<</PageOffset [ -308.5 40 ]>> setpagedevice"')

Как я могу использовать вышеупомянутая опция?

Редактировать

Пытался завершить -c с -f, но не повезло

$ node index.js
gs command: -dSAFER,-dBATCH,-dNOPAUSE,-dTextAlphaBits=4,-dGraphicsAlphaBits=4,-dDEVICEWIDTHPOINTS=238,-dDEVICEHEIGHTPOINTS=149.5,-dFIXEDMEDIA,-r150,-dDownScaleFactor=2,-sPDFPassword=01011977,-sDEVICE=jpeg,-sOutputFile=/home/jcol/Desktop/gs_offline/functions/output.jpeg,-c <</PageOffset[-64.2 40]>>setpagedevice,-f,/home/jcol/Desktop/gs_offline/functions/pan.pdf
Suceess
GPL Ghostscript 9.20 (2016-09-26)
Copyright (C) 2016 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 1.
Page 1
Loading NimbusSans-Regular font from %rom%Resource/Font/NimbusSans-Regular... 4244908 2808684 2600016 1250276 3 done. 

1 Ответ

0 голосов
/ 03 апреля 2020

В отсутствие файла примера (и, в идеале, фактической командной строки, отправляемой в Ghostscript), а также отсутствия вывода на обратном канале (stout и stderr), я могу сделать только одно замечание: Ссылка на (на самом деле часть программирования на PostScript) вводит ввод PostScript с переключателем -c, но не завершает его с -f. Это означает, что все, что следует за этим в строке команды, будет рассматриваться как большее количество PostScript, что может привести либо к ошибке, либо к «зависанию» в ожидании большего ввода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...