Assume I have a Table
---------Image-------------
imageFile (File) | thumbnail (File) | Post (a pointer to Post)
Any idea how to write a cloud code to take a smaller version of that image in another column?
For example, If a user uploaded a (2000x3500 px) image, Parse will save it in imageFile column, and save its thumbnail in the other column
thanks
Here's the current solution I'm using (Original script was published by Parse.com some time ago and deleted after the ownership transfer to the community):
Usage example in main.js:
var resizeImageKey = require('cloud/resize-image-key.js'),
THUMBNAIL_SIZE = 100,
Image = require("parse-image");
Parse.Cloud.afterSave("TableName", function(request) {
return resizeImageKey({
object: request.object, // ParseObject in which the thumbnail will be saved
url: objectImage.url(), // Full size image URL
toKey: "thumbnail", // thumbnail's attribute key
width: THUMBNAIL_SIZE, // width
crop: false // resize or crop ?
});
});
resize-image-key.js (async-await)
const Image = require("parse-image");
/*
Original: https://github.com/ParsePlatform/Anyimg/blob/master/parse/cloud/resize-image-key.js
Resizes an image from one Parse Object key containing
a Parse File to a file object at a new key with a target width.
If the image is smaller than the target width, then it is simply
copied unaltered.
object: Parse Object
url: URL of the Parse File
toKey: Key to contain the target Parse File
width: Target width
crop: Center crop the square
*/
module.exports = function(options) {
let format, originalHeight, originalWidth, newHeight, newWidth;
// First get the image data
const response = await Parse.Cloud.httpRequest({
//url: options.object.get(options.fromKey).url()
url: options.url
})
let image = new Image();
await image.setData(response.buffer);
// set some metadata that will be on the object
format = image.format();
originalHeight = image.height();
originalWidth = image.width();
if (image.width() <= options.width) {
// No need to resize
// Remove from code
} else {
var newWidth = options.width;
var newHeight = options.width * image.height() / image.width();
// If we're cropping to a square, then we need to adjust height and
// width so that the greater length of the two fits the square
if (options.crop && (newWidth > newHeight)) {
var newHeight = options.width;
var newWidth = newHeight * image.width() / image.height();
}
// resize down to normal width size
image = await image.scale({
width: newWidth,
height: newHeight
});
}
// crop ?
if (options.crop) {
let left = 0;
let top = 0;
// Center crop
if (image.width() > image.height()) {
left = (image.width() - image.height()) / 2;
} else {
top = (image.height() - image.width()) / 2;
}
image = await image.crop({
left: left,
top: top,
width: options.width,
height: options.width
});
}
newHeight = image.height();
newWidth = image.width();
// Get the image data in a Buffer.
const buffer = await image.data();
// Save the image into a new file.
const base64 = buffer.toString("base64");
//var scaled = new Parse.File("thumbnail_" + options.object.get("name") + "." + format, {
const scaled = new Parse.File("thumbnail." + format, {
base64: base64
});
const savedImage = await scaled.save();
// Set metadata on the image object
options.object.set(options.toKey, savedImage);
//return options.object.save();
options.object.set("thumbnail_width", newWidth);
options.object.set("thumbnail_height", newHeight);
};
resize-image-key.js (vanilla JS)
var Image = require("parse-image");
/*
Original: https://github.com/ParsePlatform/Anyimg/blob/master/parse/cloud/resize-image-key.js
Resizes an image from one Parse Object key containing
a Parse File to a file object at a new key with a target width.
If the image is smaller than the target width, then it is simply
copied unaltered.
object: Parse Object
url: URL of the Parse File
toKey: Key to contain the target Parse File
width: Target width
crop: Center crop the square
*/
module.exports = function(options) {
var format, originalHeight, originalWidth, newHeight, newWidth;
// First get the image data
return Parse.Cloud.httpRequest({
//url: options.object.get(options.fromKey).url()
url: options.url
}).then(function(response) {
var image = new Image();
return image.setData(response.buffer);
}).then(function(image) {
// set some metadata that will be on the object
format = image.format();
originalHeight = image.height();
originalWidth = image.width();
if (image.width() <= options.width) {
// No need to resize
return new Parse.Promise.as(image);
} else {
var newWidth = options.width;
var newHeight = options.width * image.height() / image.width();
// If we're cropping to a square, then we need to adjust height and
// width so that the greater length of the two fits the square
if (options.crop && (newWidth > newHeight)) {
var newHeight = options.width;
var newWidth = newHeight * image.width() / image.height();
}
// resize down to normal width size
return image.scale({
width: newWidth,
height: newHeight
});
}
}).then(function(image) {
if (options.crop) {
var left = 0;
var top = 0;
// Center crop
if (image.width() > image.height()) {
var left = (image.width() - image.height()) / 2;
} else {
var top = (image.height() - image.width()) / 2;
}
return image.crop({
left: left,
top: top,
width: options.width,
height: options.width
});
} else {
return Parse.Promise.as(image);
}
}).then(function(image) {
newHeight = image.height();
newWidth = image.width();
// Get the image data in a Buffer.
return image.data();
}).then(function(buffer) {
// Save the image into a new file.
var base64 = buffer.toString("base64");
//var scaled = new Parse.File("thumbnail_" + options.object.get("name") + "." + format, {
var scaled = new Parse.File("thumbnail." + format, {
base64: base64
});
return scaled.save();
}).then(function(image) {
// Set metadata on the image object
options.object.set(options.toKey, image);
//return options.object.save();
options.object.set("thumbnail_width", newWidth);
options.object.set("thumbnail_height", newHeight);
});
};
Update: Found a clone of the original script and archived it just in case: https://web.archive.org/web/20190107225015/https://github.com/eknight7/Anyimg/blob/master/parse/cloud/resize-image-key.js