如何在客户端上调整图像大小,而不是工作

时间:2013-10-31 19:28:38

标签: javascript html html5

好的,我正处于这个问题的最后阶段。我正在尝试使用Javascript在客户端上调整上传的图像。

我正在使用,

    <script>                    
function uploadFiles() {
    if (window.File && window.FileReader && window.FileList && window.Blob) {
        if (!document.getElementById('confirm').checked) {
            alert('You must click "confirm".');
            return false;
        }
        alert('begin');
        var files = document.getElementById('file').files;
        for(var i = 0; i < files.length; i++) {
            alert('start');
            resizeAndUpload(files[i]);
        }
        return false;
    } else {
        alert('The File APIs are not fully supported in this browser.');
        return false;
    }
}

function resizeAndUpload(file) {
    var reader = new FileReader();
    reader.onloadend = function() {

    var tempImg = new Image();
    tempImg.src = reader.result;
    tempImg.onload = function() {

        var MAX_WIDTH = 300;
        var MAX_HEIGHT = 300;
        var tempW = tempImg.width;
        var tempH = tempImg.height;
        if (tempW > tempH) {
            if (tempW > MAX_WIDTH) {
               tempH *= MAX_WIDTH / tempW;
               tempW = MAX_WIDTH;
            }
        } else {
            if (tempH > MAX_HEIGHT) {
               tempW *= MAX_HEIGHT / tempH;
               tempH = MAX_HEIGHT;
            }
        }

        var canvas = document.createElement('canvas');
        canvas.width = tempW;
        canvas.height = tempH;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(this, 0, 0, tempW, tempH);

        var fd = new FormData();
        fd.append("upload-avatar", "Upload");
        var confirm = 'off';
        if (document.getElementById('confirm').checked) {
            confirm = 'on';
        }
        fd.append("confirm", confirm);
        fd.append("file", canvas.mozGetAsFile("image.jpg"));
        fd.append("license", document.getElementById('license').value);
        fd.append("name", document.getElementById('name').value);
        var share = 'off';
        if (document.getElementById('share').checked) {
            share = 'on';
        }
        fd.append("share", share);
        var xhr = new XMLHttpRequest();
        xhr.open("POST", "MyUploadServlet");
        xhr.send(fd);
        alert('done');
      }

   }
   reader.readAsDataURL(file);
}
</script>

然后在我的HTML中,

<form onsubmit="return uploadFiles()" method="post" enctype="multipart/form-data">
  <input id="file" type="file" name="file" multiple/><br/>
  <input id="confirm" type="checkbox" name="confirm">confirm</input><br/>
  ...
  <input name="upload-resize" value="Upload and resize" type="submit"/><br/>
</form>

这实际上是有效的,但页面没有重新加载,我希望它能够显示上传的图像。如果我从我认为会导致重新加载的函数返回true,那么它不起作用,它似乎永远不会调用帖子并挂起。 我也尝试过location.reload()但类似的问题。

好的我想我对这段代码有几个问题:

1 - 如何重新加载页面?

- &GT;答案似乎是“history.go(0);”,这似乎有效,

2 - 这仅适用于Firefox,而不适用于Chrome,IE或Safari 我假设因为使用了“canvas.mozGetAsFile(”image.jpg“)”, 知道如何让它在Chrome上运行吗?

- &GT;使用toBlob似乎工作,但似乎打破页面重新加载,适用于Firefox而不是其他人(没有我没有尝试过的polyfill)

3 - 理想情况下,我会有两个按钮,一个用于调整大小,另一个用于执行正常形式提交,也不知道如何执行此操作。目前我有两份完整的表格副本,一份用于调整大小,另一份用于正常文件提交。

4 - 图像以png格式上传,如何压缩为jpeg,或者一般压缩,即使调整大小,一些图像也会显示比压缩时更大的图像。

- &GT;使用toBlob似乎给你jpg,但似乎打破了页面重新加载,适用于Firefox而不是其他人(没有我没有尝试过的polyfill)

对于多部分问题感到抱歉,但我认为任何想要这样做的人都需要所有答案。

1 个答案:

答案 0 :(得分:1)

<强> Q2 使用canvas.toBlob而不是canvas.mozGetAsFile。 There is a polyfill to increase browser compatibility.

在页面中显示的用法

var canvas = document.createElement('canvas');
canvas.toBlob(
    function (blob) {
        // the blob is the jpeg file
        var formData = new FormData();
        formData.append('file', blob, fileName);
        /* ... */
    },
    'image/jpeg'
);

<强> Q4 指定质量从0.0到1.0(最高质量)的canvas.toBlob(callback, 'image/jpeg', quality)

<强> Q3 你可以在一个表单中有多个按钮。

<form>
  <input id="file" type="file" name="file" multiple/><br/>
  <input id="confirm" type="checkbox" name="confirm">confirm</input><br/>
  ...
  <input name="upload" value="Upload" type="button"/>
  <input name="upload-resize" value="Upload and resize" type="button"/>
</form>

请注意,表单标记不包含onsubmit属性,输入类型现在是按钮而不是提交。

  <input name="upload" value="Upload" type="button" onclick="myfunction()"/>

或代替onclick属性,您可以使用addEventListener等。

<强> Q1 你不应该回到历史。您的location.reload()是正确的,但必须在发送/上传完成后完成。

xhr.onreadystatechange = function() {
if (xhr.readyState != 4)  { return; }
     location.reload();
}

XMLHttpRequest是异步的,因此即使在上传完成之前send方法也会返回!要知道发送是否已完成,请使用onreadystatechange,如上所示。

注意:您可能也想检查响应状态代码。