在客户端裁剪和上传图像,无需服务器端代码

Posted

技术标签:

【中文标题】在客户端裁剪和上传图像,无需服务器端代码【英文标题】:Crop and upload image on client-side without server-side code involve 【发布时间】:2013-06-28 11:37:23 【问题描述】:

正如标题所说。要求是能够在将裁剪后的图像上传到服务器之前裁剪图像。所有的工作都应该在客户端完成。 我听说过在服务器上裁剪图像并完全保存的方法。

但是当我使用 Parse.com 服务时。服务器端不支持图像处理,所以我需要在本地处理它并将完成的图像直接上传到 Parse.com 服务。

示例代码会很有帮助。 谢谢。

【问题讨论】:

html5 应该可以。 hacks.mozilla.org/2011/01/how-to-develop-a-html5-image-uploader 【参考方案1】:

我使用的解决方案:

首先,我使用第 3 方 javascript 库来选择像 jCrop 这样的裁剪区域。 获得坐标 (x1,x2,y1,y2) 后,我将图像的副本绘制到画布上。

          var canvas = document.getElementById('drawcanvas'); 
          var context = canvas.getContext('2d');
          canvas.width = canvas.width; // clear canvas
          var imageObj = new Image();
          imageObj.onload = function() 
            // draw cropped image
            // ...

            context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, sourceWidth, sourceHeight);

            var dataURL = canvas.toDataURL();
          ;
          imageObj.src = // image url

画完画布后,我将画布转换为 base64 格式的 DataURL。 获得 DataURL 后,我使用从互联网上找到的这个函数,它将 DataURL 转换为原始二进制数据。

DataURLConverter: function(data) 
        // convert base64 to raw binary data held in a string
        // doesn't handle URLEncoded DataURIs
        var byteString = atob(data.split(',')[1]);

        // separate out the mime component
        var mimeString = data.split(',')[0].split(':')[1].split(';')[0]

        // write the bytes of the string to an ArrayBuffer
        var ab = new ArrayBuffer(byteString.length);
        var ia = new Uint8Array(ab);
        for (var i = 0; i < byteString.length; i++) 
            ia[i] = byteString.charCodeAt(i);
        
            return ia;

获得二进制数据后,我们将其直接上传到 Parse.com。 上传以将“ia”作为数据进行解析

 var serverUrl = 'https://api.parse.com/1/files/' + fileName;
      $.ajax(
        type: "POST",
        beforeSend: function(request) 
          request.setRequestHeader("X-Parse-Application-Id", "App id");
          request.setRequestHeader("X-Parse-REST-API-Key", "API Key");
          request.setRequestHeader("Content-Type", "File type");
        ,
        url: serverUrl,
        data: ia,
        processData: false,
        contentType: false,
        success: function(data) 

        ,
        error: function(data) 

        
      );

【讨论】:

只是出于好奇,使用带有(隐藏)字段的表单的标准 HTTP/POST 包含图像的 base64 数据不起作用?【参考方案2】:

这可能是一篇旧帖子,但如果您找到了这个答案(像我一样),您可能想知道 Parse 现在允许在服务器端裁剪图像。

有关最新代码,您应该参考他们的文档:https://www.parse.com/docs/cloud_modules_guide#images

解析图像对象(来自 Parse 文档):

var Image = require("parse-image");

Parse.Cloud.httpRequest(
  url: object.get("profilePhoto").url(),
  success: function(response) 
    // The file contents are in response.buffer.
    var image = new Image();
    return image.setData(response.buffer, 
      success: function() 
        console.log("Image is " + image.width() + "x" + image.height() + ".");
      ,
      error: function(error) 
        // The image data was invalid.
      
    )
  ,
  error: function(error) 
    // The networking request failed.
  
);

裁剪图像(来自 Parse 文档):

// Crop the image to the rectangle from (10, 10) to (30, 20).
image.crop(
  left: 10,
  top: 10,
  right: 30,
  bottom: 20,
  success: function(image) 
    // The image was cropped.
  ,
  error: function(error) 
    // The image could not be cropped.
  
);

您还可以缩放、更改图像格式和创建缩略图。

【讨论】:

【参考方案3】:

好的,我终于成功了!!!经过一整天的搜索!!即使现在解析建议服务器端裁剪,客户端调整大小仍然很有趣。

检查这个: HTML5 Pre-resize images before uploading

Justin Levene 的修正效果非常好! 但是要使用 Parse.com,您需要使用

new Parse.File(name, base64: somebase64string);

这些代码对我有用(例如,我上传了一张 2M 的照片,调整后的照片将是 150k):

var dataurl = canvas.toDataURL("image/jpeg");

            var name = "image.jpg";
            var parseFile = new Parse.File(name, base64: dataurl.substring(23));

            parseFile.save().then(function()  ....

“23”是真正的 base64 字符串之前的所有字母。 dataurl的结果是“data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2……”,我们只需要“/9j/”开头的部分

祝你好运!

【讨论】:

以上是关于在客户端裁剪和上传图像,无需服务器端代码的主要内容,如果未能解决你的问题,请参考以下文章

在客户端裁剪和调整图像大小

上传时如何裁剪图像?

MUI调用照片以及裁剪和图库照片上传到服务器后端部分Flask+MUI

将图像 URI 上传到 Cloudinary

Jcrop 裁剪图像无法正常工作,正在裁剪错误的部分

如何上传/发布多个画布元素