parse-platform - 在保存到 Parse.Cloud.beforeSave 之前,如何将照片调整为多种照片尺寸

标签 parse-platform

首先让我先说我让这段代码完美地工作以获得缩略图 ( 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 表中保存相同但尺寸不同的照片?

目前我收到一条错误消息

“不能多次调用多个成功/错误”

或者有时如果确实有效,它只会保存 2 种照片尺寸中的一种。

任何关于我应该如何移动成功/错误响应的帮助将不胜感激。

或者如果我应该研究一种不同的方法来保存额外的照片尺寸。

谢谢,

最佳答案

因此,经过大量研究和反复试验后,我终于理解了 Promises 如何与 httpRequests 一起工作。

我最初在让 2 个同时的 httpRequests 彼此并行时遇到问题,因为某种原因,它被覆盖或被忽略。

这是您需要知道的。

  1. Parse.Cloud.httpRequest 返回一个 Parse.Promise 对象。

  2. 您实际上必须在 for 循环中返回对象。这意味着我将我的 Parse.Cloud.httpRequest 对象放在 for 循环外的单独函数中,我可以在 for 循环内调用它。

  3. 当您最终将所有 Promise 对象收集到一个 promises 数组中时,您可以使用 Parse.Promise.when(promises).then()... 遍历它

以下是我的代码,用于获取上传的照片、处理 2 种尺寸并将它们保存在单独的 _User 列中 - profilePictureThumb 和 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 用户,我在他们那里拼凑了这段代码。

关于parse-platform - 在保存到 Parse.Cloud.beforeSave 之前,如何将照片调整为多种照片尺寸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29032867/

相关文章:

ios - 在 ViewWillAppear 完成运行之前调用 CellForRowAtIndexPath

javascript - 将一个对象换成保存前已经存在的对象

parse-platform - Parse.com JS SDK 循环内的多个查询

java - 仅当对象内部的方法完成时才返回对象

ios - 如何使用 Swift 将注册页面添加到我的 Parse 应用程序中?

android - 如何上传 gif 文件以在 android 中解析为解析文件

android - 如何在 android 中使用解析 api 在解析服务器中上传图像

Android Spinner 适配器和 Lollipop

ios - 将CLLocationCoordinate2D转换为PFGeoPoint吗?

ios - 使用 Parse 登录删除 iOS 中的用户