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