Browse Source

Adding the generate thumbnail sample.

Change-Id: I2ec547bd1d3a878fd8d43285d858f32dd9207f19
ryanpbrewster-patch-1
Nicolas Garnier 8 years ago
parent
commit
1fa76a9fe1
  1. 6
      README.md
  2. 26
      generate-thumbnail/README.md
  3. 1
      generate-thumbnail/firebase.json
  4. 82
      generate-thumbnail/functions/index.js
  5. 12
      generate-thumbnail/functions/package.json

6
README.md

@ -42,6 +42,12 @@ Demonstrates how to automatically convert images that are uploaded to Firebase S
Uses a Firebase Storage trigger.
### [Automatically Generate Thumbnails](/generate-thumbnail)
Demonstrates how to automatically generate a thumbnail for images that are uploaded to Firebase Storage.
Uses a Firebase Storage trigger.
### [Automatically Moderate Images](/moderate-images)
Demonstrates how to automatically moderate offensive images that are uploaded to Firebase Storage by using the Google Cloud Vision API to detect offensive images and ImageMagick to blur these images.

26
generate-thumbnail/README.md

@ -0,0 +1,26 @@
# Automatically Generate Thumbnails
This sample demonstrates how to automatically generate thumbnails for each images that are uploaded to Firebase Storage.
## Functions Code
See file [functions/index.js](functions/index.js) for the thumbnail generation code.
The thumbnail generation is performed using ImagMagick which is installed by default on all Firebase Functions. This is a CLI so we execute the command from node using the [child-process-promise](https://www.npmjs.com/package/child-process-promise) package. The image is first downloaded locally from the Firebase Storage bucket to the `tmp` folder using the [google-cloud](https://github.com/GoogleCloudPlatform/google-cloud-node) SDK.
The dependencies are listed in [functions/package.json](functions/package.json).
## Trigger rules
The function triggers on upload of any file to the Firebase Functions bucket.
## Deploy and test
To deploy and test the sample:
- Create a Firebase project on the [Firebase Console](https://console.firebase.google.com) and visit the **Storage** tab.
- Deploy your project using `firebase deploy`
- Go to the Firebase Console **Storage** tab and upload an image. After a short time an thumbnail image with the same name but a `thumb_` prefix will be created in the same folder (make sure you refresh the UI to see the new file).

1
generate-thumbnail/firebase.json

@ -0,0 +1 @@
{}

82
generate-thumbnail/functions/index.js

@ -0,0 +1,82 @@
/**
* Copyright 2016 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for t`he specific language governing permissions and
* limitations under the License.
*/
'use strict';
const functions = require('firebase-functions');
const mkdirp = require('mkdirp-promise');
const gcs = require('@google-cloud/storage')();
const exec = require('child-process-promise').exec;
const LOCAL_TMP_FOLDER = '/tmp/';
// Max height and width of the thumbnail in pixels.
const THUMB_MAX_HEIGHT = 200;
const THUMB_MAX_WIDTH = 200;
// Thumbnail prefix added to file names.
const THUMB_PREFIX = 'thumb_';
/**
* When an image is uploaded in the Storage bucket We generate a thumbnail automatically using
* ImageMagick.
*/
exports.generateThumbnail = functions.storage().onChange(event => {
const filePath = event.data.name;
const filePathSplit = filePath.split('/');
const fileName = filePathSplit.pop();
const fileDir = filePathSplit.join('/') + (filePathSplit.length > 0 ? '/' : '');
const thumbFilePath = `${fileDir}${THUMB_PREFIX}${fileName}`;
const tempLocalDir = `${LOCAL_TMP_FOLDER}${fileDir}`;
const tempLocalFile = `${tempLocalDir}${fileName}`;
const tempLocalThumbFile = `${LOCAL_TMP_FOLDER}${thumbFilePath}`;
// Exit if this is triggered on a file that is not an image.
if (!event.data.contentType.startsWith('image/')) {
console.log('This is not an image.');
return null;
}
// Exit if the image is already a thumbnail.
if (fileName.startsWith(THUMB_PREFIX)) {
console.log('Already a Thumbnail.');
return null;
}
// Exit if this is a move or deletion event.
if (event.data.resourceState === 'not_exists') {
console.log('This is a deletion event.');
return null;
}
// Create the temp directory where the storage file will be downloaded.
return mkdirp(tempLocalDir).then(() => {
// Download file from bucket.
const bucket = gcs.bucket(event.data.bucket);
return bucket.file(filePath).download({
destination: tempLocalFile
}).then(() => {
console.log('The file has been downloaded to', tempLocalFile);
// Generate a thumbnail using ImageMagick.
return exec(`convert "${tempLocalFile}" -thumbnail '${THUMB_MAX_WIDTH}x${THUMB_MAX_HEIGHT}>' "${tempLocalThumbFile}"`).then(() => {
console.log('Thumbnail created at', tempLocalThumbFile);
// Uploading the Thumbnail.
return bucket.upload(tempLocalThumbFile, {
destination: thumbFilePath
}).then(() => {
console.log('Thumbnail uploaded to Storage at', filePath);
});
});
});
});
});

12
generate-thumbnail/functions/package.json

@ -0,0 +1,12 @@
{
"name": "functions",
"description": "Firebase Functions",
"dependencies": {
"@google-cloud/storage": "^0.4.0",
"child-process-promise": "^2.2.0",
"firebase": "^3.6.0",
"firebase-functions": "https://storage.googleapis.com/firebase-preview-drop/node/firebase-functions/firebase-functions-preview.latest.tar.gz",
"mkdirp": "^0.5.1",
"mkdirp-promise": "^4.0.0"
}
}
Loading…
Cancel
Save