0

わかりました、私はこれで頭がいっぱいです。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 - ページをリロードする方法は?

-> 答えは "history.go(0);" のようです。これは機能しているようでした。

2 - これは Firefox でのみ動作し、Chrome、IE、または Safari では動作しません。「canvas.mozGetAsFile("image.jpg")」を使用しているためだと思いますが、Chrome で動作させる方法はありますか?

-> toBlob の使用は機能しているようですが、ページのリロードで壊れているようです。Firefox では機能しますが、他では機能しません (まだ試していないポリフィルなし)。

3 - 理想的には、サイズ変更を行うボタンと通常のフォーム送信を行うボタンの 2 つのボタンが必要ですが、その方法もわかりません。現在、フォームの完全なコピーが 2 つあります。1 つはサイズ変更用、もう 1 つは通常のファイル送信用です。

4 - 画像は png 形式でアップロードされ、jpeg として圧縮する方法、または一般的に圧縮する方法で、サイズを変更しても、一部の画像は圧縮が失われるため、以前よりも大きく表示されます。

-> toBlobを使用するとjpgが得られるようですが、ページのリロードで壊れるようです.Firefoxでは動作しますが、他のものでは動作しません(まだ試していないポリフィルなし)

複数の部分からなる質問で申し訳ありませんが、これをやりたい人はすべての回答が必要になると思います。

4

1 に答える 1

1

Q2 は canvas.mozGetAsFile の代わりに canvas.toBlob を使用します。ブラウザの互換性を高めるポリフィルがあります。

ページに表示されている使用方法

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'
);

Q4canvas.toBlob(callback, 'image/jpeg', quality)品質を 0.0 から 1.0 (最高品質) の範囲で 指定してください

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>

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 を使用します。

注: 応答ステータス コードも確認することをお勧めします。

于 2013-11-01T14:03:34.693 に答える