如何使用Firebase功能处理抓取的图像并上传到Firebase存储?

时间:2019-01-08 11:02:18

标签: node.js firebase google-cloud-storage google-cloud-functions firebase-storage

我正在尝试从网址中获取一些高清图像,调整其大小并上传到存储中。

到目前为止,我已经得到图像,并使用sharp调整了大小。尖锐的output API使用.toFile('output.jpg').toBuffer(),但我不确定如何从此处继续。输出图像并将其上传到Firebase存储的最简单方法是什么?

到目前为止,我的代码:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

const request = require('request').defaults({ encoding: null });
const sharp = require('sharp');

exports.copyThumbnailImage = functions.firestore.document('users/{userId}/vocab/{vocabId}').onCreate((snapshot, context) => {
  // mock: copyThumbnailImage({ chosenImages: [{ googleThumbnailUrl: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQlC7Vnu9CuZlA-nTpW8TLPd8dAE456LCpeXoadUKHoxB7WEmM1rfahqsfr", mime: "image/jpeg", originalUrl: "https://storage.tenki.jp/storage/static-images/suppl/article/image/2/27/278/27810/1/large.jpg" }] }, { params: { userId: 'zYCw6DmcEiOS8Yk4QltYPikykwP2', vocabId: 1420970 } })
  const data = snapshot.data()
  const vocabId = context.params.vocabId
  const images = data.chosenImages

  const checkExistencePromises = []
  // Promises check if image ref already exists in firestore
  images.forEach(imageObj => {
    checkExistencePromises.push(db.collection('userImages').where('originalUrl', '==', imageObj.originalUrl).where('vocabId', '==', vocabId).get())
  })

  return Promise.all(checkExistencePromises)
    .then(snapshots => {
      const getImagePromises = []
      snapshots.forEach((snapshot, i) => {
        if (snapshot.empty) {
          // if image doesn't exist already, upload thumbnail to DB, add doc to userImages and add link to review
          const originalUrl = images[i].originalUrl
          getImagePromises.push(getImage(originalUrl))
        } else {
          // add link to review
        }
      })

      return Promise.all(getImagePromises)
    })
    .then(responses => {
      responses.forEach(response => {
        sharp(response).resize(200, 200).toBuffer()
        // ????????
      })
    })
    .then(() => {
    })
    .catch(error => {
      console.log(error)
    })
})

function getImage (url) {
  return new Promise((resolve, reject) => {
    request.get(url, (err, res, body) => {
      if (err) reject(err)
      resolve(body)
    })
  })
}

1 个答案:

答案 0 :(得分:2)

您可以将其保存到本地文件系统(本地/tmp磁盘)中,然后从那里上传到Cloud Storage。

看看这个官方的Cloud Functions示例:https://github.com/firebase/functions-samples/blob/master/convert-images/functions/index.js。 (我将下面的代码复制下来,以备将来参考)

尤其要看一下他们如何使用

保存临时文件。
return spawn('convert', [tempLocalFile, tempLocalJPEGFile]);

以及他们的上传方式:

return bucket.upload(tempLocalJPEGFile, {destination: JPEGFilePath});

在您的情况下,您可以致电

而不是致电spawn()
.toFile(-theTemporaryFielName-)

最后,看看关于/tmp磁盘的Write temporary files from Google Cloud FunctionAttach firebase cloud function or cache its data from cloud function call

截至2018年8月1日的Cloud Function示例代码(上面的链接)

const functions = require('firebase-functions');
const mkdirp = require('mkdirp-promise');
const gcs = require('@google-cloud/storage')();
const spawn = require('child-process-promise').spawn;
const path = require('path');
const os = require('os');
const fs = require('fs');

// File extension for the created JPEG files.
const JPEG_EXTENSION = '.jpg';

/**
 * When an image is uploaded in the Storage bucket it is converted to JPEG automatically using
 * ImageMagick.
 */
exports.imageToJPG = functions.storage.object().onFinalize((object) => {
  const filePath = object.name;
  const baseFileName = path.basename(filePath, path.extname(filePath));
  const fileDir = path.dirname(filePath);
  const JPEGFilePath = path.normalize(path.format({dir: fileDir, name: baseFileName, ext: JPEG_EXTENSION}));
  const tempLocalFile = path.join(os.tmpdir(), filePath);
  const tempLocalDir = path.dirname(tempLocalFile);
  const tempLocalJPEGFile = path.join(os.tmpdir(), JPEGFilePath);

  // Exit if this is triggered on a file that is not an image.
  if (!object.contentType.startsWith('image/')) {
    console.log('This is not an image.');
    return null;
  }

  // Exit if the image is already a JPEG.
  if (object.contentType.startsWith('image/jpeg')) {
    console.log('Already a JPEG.');
    return null;
  }

  const bucket = gcs.bucket(object.bucket);
  // Create the temp directory where the storage file will be downloaded.
  return mkdirp(tempLocalDir).then(() => {
    // Download file from bucket.
    return bucket.file(filePath).download({destination: tempLocalFile});
  }).then(() => {
    console.log('The file has been downloaded to', tempLocalFile);
    // Convert the image to JPEG using ImageMagick.
    return spawn('convert', [tempLocalFile, tempLocalJPEGFile]);
  }).then(() => {
    console.log('JPEG image created at', tempLocalJPEGFile);
    // Uploading the JPEG image.
    return bucket.upload(tempLocalJPEGFile, {destination: JPEGFilePath});
  }).then(() => {
    console.log('JPEG image uploaded to Storage at', JPEGFilePath);
    // Once the image has been converted delete the local files to free up disk space.
    fs.unlinkSync(tempLocalJPEGFile);
    fs.unlinkSync(tempLocalFile);
    return;
  });
});