Reputation: 2906
I am trying to resize an image in Parse Cloud Code following the Cloud Modules Guide.
The basic idea is as follows: when afterSave is called on a User, check if the small profile pic is null and standard profile pic is not null. If true, get the standard profile pic from Parse, read into buffer, create file, save file, then add file to User and Save. Unfortunately, the file doesn't seem to be saving properly.
Here is the cloud afterSave function:
Parse.Cloud.afterSave(Parse.User, function(request) {
...
Parse.Cloud.httpRequest({
url: request.object.get("profilePicture").url(),
success: function(response) {
// The file contents are in response.buffer.
var image = new Image();
console.log("Buffer: " + response.buffer );
console.log("Length " + response.buffer.length);
image.setData(response.buffer);
var imgData = image.data();
// Save the image into a new file.
var base64 = imgData.toString("base64");
var scaled = new Parse.File("thumbnail.png", { base64: base64 });
scaled.save().then(function() {
request.object.set("profilePictureSmall", scaled);
request.object.save();
}, function(error) {
console.log( "The file either could not be read, or could not be saved to Parse.");
});
}
});
...
});
The User object seems to save fine, but the image file that is saved is a broken image.
The strange thing is that console.log("Length " + response.buffer.length);
outputs the proper size to the console.
console.log("Buffer: " + response.buffer );
Gives output: �PNG
Any idea what's going on here?
Upvotes: 0
Views: 1374
Reputation: 16874
The issue is that setData()
is an async call, you need to wait for it to finish before you do the next bit.
http://parse.com/docs/js/symbols/Image.html#setData
Here's a snippet:
Parse.Cloud.httpRequest({
url: request.object.get("profilePicture").url()
}).then(function(response) {
var image = new Image();
return image.setData(response.buffer);
}).then(function(image) {
// make it fit in 100x100
var width = 100, height = 100;
if (image.width() > image.height()) {
// work out scaled height
height = image.height() * (100/image.width());
} else {
// work out scaled width
width = image.width() * (100/image.height());
}
console.log("..scale to " + width + "x" + height);
return image.scale({
width: width,
height: height
});
}).then(function(scaledImage) {
// get the image data in a Buffer
return scaledImage.data();
}).then(function(buffer) {
// save the image to a new file
console.log("..saving file");
var base64 = buffer.toString("base64");
var name = "Thumbnail.png";
var thumbnail = new Parse.File(name, { base64: base64 });
return thumbnail.save();
}).then(function(thumbnail) {
// attach the image file to the original object
console.log("..attaching file");
request.object.set("profilePictureSmall", thumbnail);
return request.object.save();
}) /* further chaining here for after-save */;
You basically have to chain your promises together to allow the previous step to finish.
Upvotes: 4