Создание эскизов PDF для Firebase - PullRequest
0 голосов
/ 26 апреля 2018

Я занимаюсь разработкой приложения для Android, которое управляет PDF-файлами. Я знаю, что Cloudinary позволяет пользователям загружать PDF-файлы и автоматически создавать эскизы для загруженного PDF-файла (см. здесь ). Обладает ли Firebase Storage или Cloud Firestore аналогичной функцией? Если нет, какой-либо рекомендуемый сторонний инструмент для этой задачи? Спасибо!

1 Ответ

0 голосов
/ 27 апреля 2018

Введение

ImageMagick поставляется предварительно установленным в среде облачных функций, а Ghostscript - нет (по крайней мере, не сейчас). Ghostscript - это то, что нужно для создания изображений из PDF-файлов.

Сначала загрузите копию исполняемого файла Ghostscript с здесь (версия Linux 64-битной APGL) и сохраните ее в корневом каталоге вашей функции. Вы можете переименовать имя папки / исполняемого файла для более коротких ссылок на пути. Это будет развернуто при развертывании ваших функций.

Второй, как видно из этого репо , npm install —-save https://github.com/sina-masnadi/node-gs/tarball/master. Это обертка, с которой вам нужно связаться с исполняемым файлом Ghostscript изнутри вашей функции.

В-третьих, вы можете просмотреть документы Ghostscript / ImageMagick для дальнейшей настройки.

Пример облачной функции

Наконец, вот функция, которую я только что начал работать для моей структуры файлов функций. Вам нужно будет написать лучшую проверку и настроить ее для своей настройки, но знайте, что суть этого будет работать.

const admin = require('firebase-admin');
const functions = require('firebase-functions');
const fs = require('fs');
const os = require('os');
const path = require('path');
const write = require('fs-writefile-promise');
const spawn = require('child-process-promise').spawn;
const mkdirp = require('mkdirp-promise');
const gs = require('gs');
const gs_exec_path = path.join(__dirname, '../../../ghostscript/./gs-923-linux-x86_64');

try { admin.initializeApp(functions.config().firebase); } catch(e) {}


/*
  Callable https function that takes a base 64 string of a pdf (MAX 
  10mb), uploads a thumbnail of it to firebase storage, and returns its 
  download url.
 */
module.exports = functions.https.onCall((data, context) => {
  if (!data.b64str) { throw Error('missing base 64 string of pdf!'); }

  const b64pdf = data.b64str.split(';base64,').pop();
  const pg = typeof data.pg === 'number' ? data.pg : 1; //1-based
  const max_wd = typeof data.max_wd === 'number' ? data.max_wd : 200;
  const max_ht = typeof data.max_ht === 'number' ? data.max_ht : 200;
  const st_fname = typeof data.fname === 'string' ? data.fname : 'whatever.jpg';

  const bucket = admin.storage().bucket();
  const tmp_dir = os.tmpdir();
  const tmp_pdf = path.join(tmp_dir, 'tmp.pdf');
  const tmp_png = path.join(tmp_dir, 'doesntmatter.png');
  const tmp_thumb = path.join(tmp_dir, st_fname.split('/').pop();
  const st_thumb = st_fname;

  /* create tmp directory to write tmp files to... */
  return mkdirp(tmp_dir).then(() => {
    /* create a temp pdf of the base 64 pdf */
    return write(tmp_pdf, b64pdf, {encoding:'base64'});
  }).then(() => {
    /* let ghostscript make a png of a page in the pdf */
    return new Promise((resolve, reject) => {
      gs().batch().nopause()
          .option(`-dFirstPage=${pg}`)
          .option(`-dLastPage=${pg}`)
          .executablePath(gs_exec_path)
          .device('png16m')
          .output(tmp_png)
          .input(tmp_pdf)
          .exec(err => err ? reject(err) : resolve());
    });
  }).then(() => {
    /* make a thumbnail for the png generated by ghostscript via imagemagick */
    var args = [ tmp_png, '-thumbnail', `${max_wd}x${max_ht}>`, tmp_thumb ];
    return spawn('convert', args, {capture: ['stdout', 'stderr']});
  }).then(() => {
    /* upload tmp_thumb to storage. */
    return bucket.upload(tmp_thumb, { destination: st_thumb });
  }).then(() => {
    /* get storage url for the uploaded thumbnail */
    return bucket.file(st_thumb).getSignedUrl({
      action:'read',
      expires: '03-01-2500'
    });
  }).then(result => {
    /* clean up temp files and respond w/ download url */
    fs.unlinkSync(tmp_pdf);
    fs.unlinkSync(tmp_png);
    fs.unlinkSync(tmp_thumb);
    return result[0];
  });
});

Пример вызова от клиента

var fn = firebase.functions().httpsCallable('https_fn_name');

fn({
  b64str: 'base64 string for pdf here....',
  pg: 2, //optional, which page do u want a thumbnail of? 1 is the first.
  fname: 'path/to/file/in/storage.jpg', //optional but recommended, .png if u like
  max_wd: 300, // optional, max thumbnail width
  max_ht: 300  // optional, max thumbnail height
}).then(res => console.log(res));

Если вы не можете сгенерировать подписанный URL-адрес ...

Вам потребуется Добавить роль «Агент службы облачных функций» к любой учетной записи службы, которую использует эта функция. Вы можете добавить роль к своей учетной записи службы в облачной консоли .

How to add the role

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