【问题标题】:toDataURL's output is base64, how to reduce the uploading time and bandwidth of a factor 1/3?toDataURL的输出是base64,如何将上传时间和带宽减少1/3?
【发布时间】:2018-12-09 15:55:36
【问题描述】:

以下代码的目标是压缩输入文件(2 MB JPG 文件 => 500 KB 文件),然后在提交<form> 时将其上传到服务器。

将图像从 JPG 文件导入画布并使用 toDataURL 导出时:

function doit() {
    var file = document.getElementById('file').files[0],
        canvas = document.getElementById('canvas'),
        hidden = document.getElementById('hidden'),
        ctx = canvas.getContext("2d"),
        img = document.createElement("img"),
        reader = new FileReader();  
    
    reader.onload = function(e) { 
        img.src = e.target.result;
    }
    
    img.onload = function () { 
        ctx.drawImage(img, 0, 0);
        hidden.value = canvas.toDataURL("image/jpeg", 0.5);
    }
    reader.readAsDataURL(file);
}
<input type="file" onchange="doit();" id="file" />

<form action="/upload" method="post">
<input type="hidden" id="hidden" />
<input type="submit" />
</form>

<canvas id="canvas" style="display: none" />

它可以工作,但&lt;form&gt; 中的输出hidden 字段是base64 编码的,即类似于:

data:image/jpeg;base64,/9j/4AAQSkZJRgAB...

众所周知,base64 使用的二进制数据是正常大小的 1.3333 倍。

问题:在这种情况下,即提交&lt;form&gt;时,如何避免浪费1/3的数据在上传时间(客户端=>服务器)和带宽上?

注意:我认为如果我使用 AJAX 而不是 &lt;form&gt; 提交,问题会一样,不是吗?

【问题讨论】:

  • 为什么不简单地img.src = window.URL.createObjectURL(file)
  • @bigless 我们的目标不是仅仅将文件加载到img 中,而是压缩它(2 MB JPG 文件 => 500 KB 文件,因此是“质量因子”,这里0.5,很重要),然后在提交
    或使用 AJAX
    时将其上传到服务器

标签: javascript ajax html5-canvas base64


【解决方案1】:

var jsForm = null;

function doit() {
    var file = document.getElementById('file').files[0],
        canvas = document.getElementById('canvas'),
        ctx = canvas.getContext("2d"),
        img = document.createElement("img");

    img.src = window.URL.createObjectURL(file);
    
    img.onload = function () {
        if (!jsForm) {
          jsForm = new FormData();
        }
        ctx.drawImage(img, 0, 0);
        canvas.toBlob(function(blob) {
          jsForm.set('image', blob, file.name);
        }, "image/jpeg", 0.5);
    }
}

var form = document.getElementById('form');
form.onsubmit = function(e) {
  e.preventDefault();
  if (!jsForm) return;
  var request = new XMLHttpRequest();
  request.open(this.method||'POST', this.action||'/');
  request.send(jsForm);
  jsForm = null;
}
<form method="POST" action ="/upload" id="form">
  <input type="file" onchange="doit();" id="file" />
  <button>Submit</button>
</form>
<canvas id="canvas" style="display: none" />

【讨论】:

  • 非常感谢。不是立即request.openrequest.send,而是如何将此表单数据添加到现有的&lt;form id="form1"&gt; &lt;input ...&gt; ... &lt;/form&gt; 中,该&lt;form id="form1"&gt; &lt;input ...&gt; ... &lt;/form&gt; 还包含一个submit 按钮,从而允许用户选择何时发布表单?
  • @Basj 您不能以编程方式处理文件输入,这意味着您必须使用 ajax。我更新了答案。
猜你喜欢
  • 2012-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-09
  • 2021-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多