Parse platform 在保存到Parse.Cloud.beforeSave之前,如何将照片调整为多个照片大小

Parse platform 在保存到Parse.Cloud.beforeSave之前,如何将照片调整为多个照片大小,parse-platform,Parse Platform,首先,让我首先说,我让这段代码完美地工作,以获得缩略图() 我目前的代码是: var Image = require("parse-image"); var photoSizesArray = {}; photoSizesArray["Thumb"] = [40,40]; photoSizesArray["Normal"] = [180,180]; Parse.Cloud.beforeSave("_User", function(request, response) {

首先,让我首先说,我让这段代码完美地工作,以获得缩略图()

我目前的代码是:

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);
          });

      }
    }
  });
我的问题是如何在同一个用户表中保存同一张照片但大小不同

目前我收到一个错误,上面写着

“无法多次调用多个成功/错误”

或者有时候,如果它确实有效,它只会保存两种照片大小中的一种

如果您能为我提供有关如何处理成功/错误响应的任何帮助,我们将不胜感激

或者,如果我应该寻找一种不同的方法来保存额外的照片大小


谢谢,

首先,您不必每次都加载源映像。加载一次,然后多次调整大小

不能重复使用同一图像对象,因此必须为每个单独的调整大小操作创建所需数量的对象

大致流程如下所示:

var grandPromise = Parse.Cloud.httpRequest({ url: url })
        .then(function (response) {
            var buffer = response.buffer;
            var promises = [];
            var sizes = { 
                normal: { width: 300, height: 300 }, 
                thumb: { width: 100, height: 100 }
            };

            for(var key in sizes) {
                var size = sizes[key];
                var image = new Image();

                // create promise for resize operation
                var promise = image.setData(buffer)
                    .then(function(image) {
                        // do whatever scaling you want
                        return image.scale({
                            width: size.width, 
                            height: size.height
                        });
                    })
                    .then(function (scaledImage) {
                        return scaledImage.data();
                    })
                    .then(function (buffer) {
                        var base64 = buffer.toString('base64');
                        var name = key + '.jpg';
                        var file = new Parse.File(name, { base64: base64 });

                        return file.save()
                             .then(function (file) {
                                 // this object is passed to promise below
                                 return { 
                                     key: key, 
                                     size: size, 
                                     file: file
                                 };
                             });
                    });

                // save promise to array
                promises.push(promise);
            }

            // create promise that waits for all promises
            return Parse.Promise
                    .when(promises)
                    .then(function ( /* result1, result2, ... */ ) {
                        // results are passed as function arguments
                        // map processed photos to result
                        var photos = Array.prototype.slice.call(arguments);
                        var result = {};

                        photos.forEach(function (photo) {
                            result[photo.key] = photo;
                        });

                        return result;
                    });
        });

grandPromise.then(function (result) {
   var normalURL = result.normal.file.url();
   var thumbURL = result.thumb.file.url();

   // save URLs on user model
   user.set('profilePictureNormal', normalURL);
   user.set('profilePictureThumb', thumbURL);

   console.log('Saved normal size photo at ' + normalURL);
   console.log('Saved thumb size photo at ' + thumbURL);

   response.success();
}, function (err) {
    console.log('Got error ' + err.code + ' : ' + err.message);
    response.error(err);
});

所以,经过一系列的研究和反复试验,我终于明白了承诺是如何与httprequest一起工作的

最初,我在让两个同时进行的httprequest相互并行时遇到了问题,因为某种原因,它被覆盖或被忽略

这是你需要知道的

  • Parse.Cloud.httpRequest返回Parse.Promise对象

    • 这意味着它有一个
      。然后
      错误
      功能(此处阅读更多信息:
  • 实际上,您必须在for循环中返回对象。这意味着我将Parse.Cloud.httpRequest对象放在for循环之外的单独函数中,我可以在for循环中调用该函数

  • 当您最终将所有Promise对象收集到promises数组中时,您可以使用Parse.Promise.When(promises.then()

  • 下面是我的代码,它获取上传的照片,处理2种大小的照片,并将它们保存在单独的用户列中—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用户,我拼凑了这段代码。

    非常感谢,我还有一个问题希望您能帮助我,所以我有两个专栏,一个是profilePictureThumb,另一个是profilePictureNormal。在这段代码中,我把处理过的照片放在哪里?:OAppare在
    grandPromise.then()
    中,您可以执行类似
    user.set('profilePictureNormal',results.normalPhoto.file.url());
    的操作。在上面的代码中,我按大小将图像存储在对象中,但您可以使用任何键。嗨,安迪,非常感谢您的帮助,尽管我在使用上面的代码时遇到了这个错误。[错误]:TypeError:无法读取指向var normalURL=result.normal.file.url()的未定义属性“file”;知道原因吗?@jaysong我不知道,我在上面的代码中没有变量“normalPhoto”。调试代码。调试后,我在for(var key in size)中找到了该属性循环时,代码似乎同时运行。而不是一个接一个地运行。因此产生以下控制台。欢迎使用logYou。此外,建议在保存前使用
    (Parse.User,
    )而不是字符串
    “\u User”
    ,或者如果你像我一样使用
    Parse.User
    的子类,你可以传递你的子类。还要记住,当用户是通过Parse创建的,例如在注册Facebook时,
    profilePicture
    可能是空的。所以你可能想忽略这一点,我使用
    User.existed()
    检查用户是否已创建或更新。您好。我实现了您的解决方案,图像尽可能呈颗粒状。有什么建议吗?您好,我实现了此解决方案,效果很好,它还可以上载原始图像。如何仅上载调整大小的图像而不上载原始图像?