在 Parse.Cloud.beforeSave 中保存之前,如何将照片调整为多种照片尺寸 [英] How do I resize a photo into multiple photo sizes before saving in Parse.Cloud.beforeSave
问题描述
首先让我说我让这段代码完美地运行以获得缩略图(https://parse.com/docs/cloud_modules_guide#images)
First off let me start by saying I got this code working perfectly to get a thumbnail (https://parse.com/docs/cloud_modules_guide#images)
我当前的代码是:
var Image = require("parse-image");
var photoSizesArray = {};
photoSizesArray["Thumb"] = [40,40];
photoSizesArray["Normal"] = [180,180];
Parse.Cloud.beforeSave("_User", function(request, response) {
var user = request.object;
if (!user.get("profilePicture")) {
// response.error("Users must have a profile photo.");
// return;
response.success();
return;
} else {
if (!user.dirty("profilePicture")) {
// The profile photo isn't being modified.
response.success();
return;
}
for (var key in photoSizesArray) {
Parse.Cloud.httpRequest({
url: user.get("profilePicture").url()
}).then(function(response) {
var image = new Image();
return image.setData(response.buffer);
}).then(function(image) {
// Crop the image to the smaller of width or height.
var size = Math.min(image.width(), image.height());
return image.crop({
left: (image.width() - size) / 2,
top: (image.height() - size) / 2,
width: size,
height: size
});
}).then(function(image) {
// Resize the image to 40 x 40.
return image.scale({
width: photoSizesArray[key][0],
height: photoSizesArray[key][1]
});
}).then(function(image) {
// Make sure it's a JPEG to save disk space and bandwidth.
return image.setFormat("JPEG");
}).then(function(image) {
// 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 cropped = new Parse.File("profilePicture"+key+"_" + Parse.User.current().id + ".jpg", { base64: base64 });
return cropped.save();
}).then(function(cropped) {
// Attach the image file to the original object.
user.set("profilePicture" + key, cropped);
}).then(function(result) {
response.success();
}, function(error) {
response.error(error);
});
}
}
});
我的问题是如何在同一个 _User 表中保存相同但大小不同的照片?
My question is how do I go about saving the same photo but a different size in the same _User table?
目前我收到一个错误提示
Currently I'm getting an error that says
不能多次调用多个成功/错误"
"Can't call multiple success/error multiple times"
或者有时如果它确实有效,它只会保存两种照片尺寸中的一种.
or sometimes if it does work, it'll only save one of the 2 photo sizes.
对于我应该如何移动成功/错误响应的任何帮助,我们将不胜感激.
Any help would be appreciated on how I should move the success/error response around.
或者我是否应该研究另一种方法来保存额外的照片尺寸.
OR if I should be looking into a different approach on how to save an additional photo size.
谢谢,
推荐答案
所以经过大量的研究和反复试验,我终于明白 Promises 如何与 httpRequests 一起工作.
So after a whole bunch research and trial and error, I finally understand how Promises work along side with httpRequests.
我最初在让 2 个同时并行的 httpRequests 并行时遇到问题,因为某种原因,它被覆盖或被忽略.
I initially had problems getting 2 simultaneous httpRequests going parallel to each other as for some reason, it gets overwritten or just ignored.
以下是您需要了解的内容.
Here's what you need to know.
Parse.Cloud.httpRequest 返回一个 Parse.Promise 对象.
Parse.Cloud.httpRequest returns a Parse.Promise object.
- 这意味着它有一个
.then
和error
函数(在这里阅读更多:在此处输入链接描述
- this means that it has a
.then
anderror
functions (read more here: enter link description here
您实际上必须在 for 循环中返回对象.这意味着我将 Parse.Cloud.httpRequest 对象放置在 for 循环之外的单独函数中,我可以在 for 循环中调用该函数.
you actually have to RETURN the object in a for loop. This meant me placing my Parse.Cloud.httpRequest object in a separate function outside the for loop that I can call within the for loop.
当您最终将所有 Promise 对象收集到一个 promises 数组中时,您可以使用 Parse.Promise.when(promises).then()...
When you finally have all the Promise Objects collected in a promises array, you go through it using Parse.Promise.when(promises).then()...
以下是我的代码,用于获取上传的照片、处理 2 种尺寸的照片并将它们保存在单独的 _User 列中 - profilePictureThumb 和 profilePictureNormal.
The following is my code that gets an uploaded photo, processes 2 sizes of it and saves them in separate _User columns - profilePictureThumb and profilePictureNormal.
var Image = require("parse-image");
Parse.Cloud.beforeSave("_User", function(request, response) {
var user = request.object;
if (!user.get("profilePicture")) {
// response.error("Users must have a profile photo.");
// return;
response.success();
return;
} else {
if (!user.dirty("profilePicture")) {
// The profile photo isn't being modified.
response.success();
return;
}
var promises = [];
var sizes = {
Normal: { width: 180, height: 180 },
Thumb: { width: 80, height: 80 }
};
for(var key in sizes) {
promises.push(
ProcessUrls(user.get("profilePicture").url(), key, sizes[key])
);
}
return Parse.Promise
.when(promises)
.then(function () {
// results are passed as function arguments
// map processed photos to result
var photos = Array.prototype.slice.call(arguments);
var result = {};
console.log("promises:" + promises)
photos.forEach(function (photo) {
console.log("photo.key: " + photo.key)
result[photo.key] = photo;
user.set('profilePicture' + photo.key, photo.file);
});
response.success();
}, function(error) {
response.error("error: " + error);
});
} // Else
});
function ProcessUrls(fullUrl, key, size) {
/* debugging
console.log("fullUrl: " + fullUrl);
console.log("key: " + key);
console.log("width: " + size["width"]);
console.log("height: " + size["height"]);
*/
return Parse.Cloud.httpRequest({ url: fullUrl })
.then(function(response) {
var image = new Image();
return image.setData(response.buffer);
})
.then(function(image) {
// Crop the image to the smaller of width or height.
var size = Math.min(image.width(), image.height());
return image.crop({
left: (image.width() - size) / 2,
top: (image.height() - size) / 2,
width: size["width"],
height: size["height"]
})
})
.then(function(image) {
// Resize the image to 40 x 40.
return image.scale({
width: size["width"],
height: size["height"]
});
})
.then(function(image) {
// Make sure it's a JPEG to save disk space and bandwidth.
return image.setFormat("JPEG");
})
.then(function(image) {
// 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 cropped = new Parse.File("profilePicture"+key+"_" + Parse.User.current().id + ".jpg", { base64: base64 });
return cropped.save()
.then(function (file) {
// this object is passed to promise below
return {
key: key,
file: file
};
})
})
};
感谢@Andy 和一大群其他 StachOverflow 用户,我将这些代码拼凑在一起.
Thanks to @Andy and a whole bunch of other StachOverflow users where I cobbled up this code together.
这篇关于在 Parse.Cloud.beforeSave 中保存之前,如何将照片调整为多种照片尺寸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!