I've started using Cloud Functions for Firebase to crop and resize multiple sizes when an image gets uploaded to my Firebase storage. I used the Firebase example code to get me started. Using the ImageMagick commands. However, I'm not getting crop to work.
It's my goal to get functionality, the same way Wordpress does. Upload image x. Make a fixed ratio crop. And resize to 3 sizes.
The code I have now resizes to a medium and large image and uploads them into my storage. Anyone have an approach on how to get the crop working?
This is my code so far:
'use strict';
const functions = require(`firebase-functions`);
const mkdirp = require(`mkdirp-promise`);
const gcs = require(`@google-cloud/storage`)();
const spawn = require(`child-process-promise`).spawn;
const LOCAL_TMP_FOLDER = `/tmp/`;
// Thumbnail prefix added to file names.
const THUMB_PREFIX_LARGE = `large_`;
const THUMB_PREFIX_MEDIUM = `medium_`;
/**
* When an image is uploaded in the Storage bucket We generate a thumbnail automatically using
* ImageMagick.
*/
exports.generateThumbnail = functions.storage.object().onChange(event => {
const filePath = event.data.name;
const filePathSplit = filePath.split(`/`);
const fileName = filePathSplit.pop();
const fileDir = filePathSplit.join(`/`) + (filePathSplit.length > 0 ? `/` : ``);
const thumbFilePathLarge = `${fileDir}${THUMB_PREFIX_LARGE}${fileName}`;
const thumbFilePathMedium = `${fileDir}${THUMB_PREFIX_MEDIUM}${fileName}`;
const tempLocalDir = `${LOCAL_TMP_FOLDER}${fileDir}`;
const tempLocalFile = `${tempLocalDir}${fileName}`;
const tempLocalThumbFileLarge = `${LOCAL_TMP_FOLDER}${thumbFilePathLarge}`;
const tempLocalThumbFileMedium = `${LOCAL_TMP_FOLDER}${thumbFilePathMedium}`;
// 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;
}
// Exit if the image is already a thumbnail.
if (fileName.startsWith(THUMB_PREFIX_LARGE) || fileName.startsWith(THUMB_PREFIX_MEDIUM)) {
console.log(`Already a Thumbnail.`);
return;
}
// Exit if this is a move or deletion event.
if (event.data.resourceState === `not_exists`) {
console.log(`This is a deletion event.`);
return;
}
// 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 LARGE thumbnail using ImageMagick.
return spawn(`convert`, [tempLocalFile, `-thumbnail`, `1200x800`, tempLocalThumbFileLarge]).then(() => {
console.log(`Thumbnail created at`, tempLocalThumbFileLarge);
// Uploading the large Thumbnail.
return bucket.upload(tempLocalThumbFileLarge, {
destination: thumbFilePathLarge
}).then(() => {
console.log(`Thumbnail uploaded to Storage at`, thumbFilePathLarge);
}).then(() => {
console.log(`The file has been downloaded to`, tempLocalFile);
// Generate a MEDIUM thumbnail using ImageMagick.
return spawn(`convert`, [tempLocalFile, `-thumbnail`, `600x400`, tempLocalThumbFileMedium]).then(() => {
console.log(`Thumbnail created at`, tempLocalThumbFileMedium);
// Uploading the medium Thumbnail.
return bucket.upload(tempLocalThumbFileMedium, {
destination: thumbFilePathMedium
}).then(() => {
console.log(`Thumbnail uploaded to Storage at`, thumbFilePathMedium);
});
});
});
});
});
});
});