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

查看:17
本文介绍了在 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.

  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天全站免登陆