Skip to content

Instantly share code, notes, and snippets.

@leonimurilo
Last active April 9, 2021 02:06
Show Gist options
  • Save leonimurilo/752f39a6713e8d349665c279d1a5886f to your computer and use it in GitHub Desktop.
Save leonimurilo/752f39a6713e8d349665c279d1a5886f to your computer and use it in GitHub Desktop.
How to save multiple versions of an image on Google cloud storage using cloud functions
const { Storage } = require('@google-cloud/storage');
const sharp = require('sharp');
const variations = [
{ prefix: 'thumb', width: 120 },
{ prefix: 'mini', width: 480 },
{ prefix: 'med', width: 1024 }
];
/**
* Triggered from a change to a Cloud Storage bucket.
*
* @param {!Object} event Event payload.
* @param {!Object} context Metadata for the event.
*/
exports.helloGCS = async (event, context) => {
// this prevents the new created image versions from running the function and creating an endless loop
// you can also use different bucket, folder hierarchies or any other idea to better handle this
const shouldIgnore = variations.some(variation => `${event.name}`.includes(`${variation.prefix}-`));
if (shouldIgnore) {
console.log('Ignoring image...')
return null;
}
// console.log(`Processing file: ${event.name}`);
// console.log(` Event: ${context.eventId}`);
// console.log(` Event Type: ${context.eventType}`);
// console.log(` Bucket: ${event.bucket}`);
// console.log(` File: ${event.name}`);
// console.log(` Metageneration: ${event.metageneration}`);
// console.log(` Created: ${event.timeCreated}`);
// console.log(` Updated: ${event.updated}`);
const storage = new Storage();
const bucket = storage.bucket(event.bucket);
const generateImageVariation = (variation) => new Promise((resolve, reject) => {
console.log('Sharping...');
const transformer = sharp()
.resize({ width: variation.width, fit:"contain", })
.flatten({ background: { r: 255, g: 255, b: 255 } })
.withMetadata()
.jpeg();
console.log('Reading original...');
const originalBuketFile = bucket.file(event.name);
const remoteReadStream = originalBuketFile.createReadStream();
const nameWithoutOriginalPrefix = `${event.name}`.replace('original-', '');
const newFile = bucket.file(`${variation.prefix}-${nameWithoutOriginalPrefix}`);
const remoteWriteStream = newFile.createWriteStream({
contentType: 'image/jpeg',
resumable: false,
public: true
});
remoteWriteStream.on('error', () => {
console.error(`Unable to upload image, something went wrong`);
}).on('finish', async (resp) => {
console.log('terminou!');
console.log(resp);
})
console.log('Pipe started...');
remoteReadStream.pipe(transformer).pipe(remoteWriteStream);
});
const promises = variations.map(variation => generateImageVariation(variation));
await Promise.all(promises);
};
{
"name": "sample-cloud-storage",
"version": "0.0.1",
"dependencies": {
"@google-cloud/storage": "^5.1.2",
"sharp": "0.27.2"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment