在保存到Parse.Cloud.beforeSave中之前,如何将照片调整为多种照片大小 [英] How do I resize a photo into multiple photo sizes before saving in Parse.Cloud.beforeSave

查看:59
本文介绍了在保存到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"

,或者有时候,如果它确实起作用,它将仅保存2张照片尺寸之一.

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.

起初,我遇到了使两个同时发出的httpRequest相互平行的问题,由于某种原因,它被覆盖或被忽略了.

I initially had problems getting 2 simultaneous httpRequests going parallel to each other as for some reason, it gets overwritten or just ignored.

这是您需要知道的.

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

  1. Parse.Cloud.httpRequest returns a Parse.Promise object.

  • this means that it has a .then and error 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆