Dropzone.js +客户端图像大小调整

Ped*_*las 15 resize image-resizing dropzone.js

我想将Dropzone.js与客户端图像大小调整集成.我知道有一个调整缩略图大小的功能,但我想在上传之前创建一个调整主图像大小的功能.有人可以帮我吗?

rod*_*dic 12

以下是如何在不上传文件的情况下执行此操作addedfile.

重要的是设置autoQueue选项false,这样dropzone就不会自动上传用户选择的文件.

var dropzone = new Dropzone (".dropzone", {
  ...
  autoQueue: false,
  ...
});
Run Code Online (Sandbox Code Playgroud)

下一步是在addedfile事件中调整大小和排列调整大小的版本.

dropzone.on("addedfile", function(origFile) {
  var MAX_WIDTH  = 800;
  var MAX_HEIGHT = 600;

  var reader = new FileReader();

  // Convert file to img

  reader.addEventListener("load", function(event) {

    var origImg = new Image();
    origImg.src = event.target.result;

    origImg.addEventListener("load", function(event) {

      var width  = event.target.width;
      var height = event.target.height;


      // Don't resize if it's small enough

      if (width <= MAX_WIDTH && height <= MAX_HEIGHT) {
        dropzone.enqueueFile(origFile);
        return;
      }


      // Calc new dims otherwise

      if (width > height) {
        if (width > MAX_WIDTH) {
          height *= MAX_WIDTH / width;
          width = MAX_WIDTH;
        }
      } else {
        if (height > MAX_HEIGHT) {
          width *= MAX_HEIGHT / height;
          height = MAX_HEIGHT;
        }
      }


      // Resize

      var canvas = document.createElement('canvas');
      canvas.width = width;
      canvas.height = height;

      var ctx = canvas.getContext("2d");
      ctx.drawImage(origImg, 0, 0, width, height);

      var resizedFile = base64ToFile(canvas.toDataURL(), origFile);


      // Replace original with resized

      var origFileIndex = dropzone.files.indexOf(origFile);
      dropzone.files[origFileIndex] = resizedFile;


      // Enqueue added file manually making it available for
      // further processing by dropzone

      dropzone.enqueueFile(resizedFile);
    });
  });

  reader.readAsDataURL(origFile);
});
Run Code Online (Sandbox Code Playgroud)

这是一个转换dataURLdropzone文件的功能.如果使用canvas.toBlob()而不是canvas.toDataURL()来获取已调整大小的文件的内容,则进程可能更简单,但后者并非所有浏览器都支持.

它只是这个功能的修改版本.

function base64ToFile(dataURI, origFile) {
  var byteString, mimestring;

  if(dataURI.split(',')[0].indexOf('base64') !== -1 ) {
    byteString = atob(dataURI.split(',')[1]);
  } else {
    byteString = decodeURI(dataURI.split(',')[1]);
  }

  mimestring = dataURI.split(',')[0].split(':')[1].split(';')[0];

  var content = new Array();
  for (var i = 0; i < byteString.length; i++) {
    content[i] = byteString.charCodeAt(i);
  }

  var newFile = new File(
    [new Uint8Array(content)], origFile.name, {type: mimestring}
  );


  // Copy props set by the dropzone in the original file

  var origProps = [ 
    "upload", "status", "previewElement", "previewTemplate", "accepted" 
  ];

  $.each(origProps, function(i, p) {
    newFile[p] = origFile[p];
  });

  return newFile;
}
Run Code Online (Sandbox Code Playgroud)

  • 通过这种方式使用"jpeg"可以实现更好的压缩(修改一行):var resizedFile = base64ToFile(canvas.toDataURL("image/jpeg"),origFile); (2认同)
  • 我一直在对此进行故障排除,导致iOS上的Safari问题的行是:var newFile = new File([new Uint8Array(content)],origFile.name,{type:mimestring}); 据推测,它与iOS的严格许可或缺少可从Web浏览器访问的文件系统有关. (2认同)

Chr*_*ini 11

有关预上载调整大小功能的Dropzone文档令人困惑.它的读取方式,你可以限制宽度,限制高度,或限制两者,牺牲宽高比,扭曲图像.不是这种情况.这个:

resizeWidth: 1000, resizeHeight: 1000,
resizeMethod: 'contain', resizeQuality: 1.0,
Run Code Online (Sandbox Code Playgroud)

宽度或高度限制最大1000px - 以较大者为准.另一个将根据宽高比减少,而不会扭曲图像.例如,在我的测试中,我上传了一张2688x1512图片.Dropzone裁剪并将缩略图调整为其默认值120x120,但发送到服务器的文件由Dropzone单独调整为1000x562,然后发送到服务器.

这里有一个有趣的警告.JPEG将被重新压缩,有损,因此即使resizeQuality为1.0也会导致丢失.我将此功能视为一种防止疯狂大文件的方法,但是如果可以避免它,则应该小心两次调整大小(一次在服务器上一次在客户端上).

如果这对你来说还不够 - 而且你真的想要重载转换方法 - 值得注意的是,遵循Dropzone中的代码路径有点令人困惑,因为createThumbnail每次上传都会使用两次代码路径,一次创建像你这样的缩略图期望,并再次预先调整图像大小,然后再将其传递给服务器.同样,这种resize方法令人困惑地命名; 而resizeWidth等指的是准备上传图像,调整大小是指调整缩略图的大小,对发送到服务器的图像不做任何操作.


Hoo*_*ini 7

Dropzone 版本 5 最近发布,因此如果您升级到 dropzone 5,那么您可以简单地使用resizeWidthresizeHeigh在客户端压缩您的图像。

如果您只提供其中之一,则 dropzone 将尊重原始纵横比,例如,如果您只添加选项:resizeWidth: 800那么您的图像将被压缩为width=800像素,并且您的原始图像的纵横比将得到尊重。


小智 4

可以通过绕过 Dropzone.js 完成的上传来完成。为此,您必须autoQueue: false在选项中进行设置(如Bootstrap 示例中所示)。

然后您可以只发送缩略图,或者您也可以通过困难的方式来完成。


解决方案 1:发送缩略图

myDropzone.on('thumbnail', function(file, dataURL) {
   $.post('http://example.com', {img: imgToSend})
})
Run Code Online (Sandbox Code Playgroud)

您可以通过在选项中添加调整大小功能来定义调整大小/裁剪的方式。


解决方案2:自行调整大小

还有另一个问题:图像可能需要旋转(这种情况经常发生)。为此,必须使用 EXIF 方向标签。当您调整大小时,它显然会丢失,因此您必须在调整大小之前在前端获取此信息。为此,我使用了Exif.js 库

这是JSFiddle 上的一个工作示例。您可以在控制台中看到调整大小后的图像的数据 URI。