web-dev-qa-db-ja.com

サーバーにアップロードする前にJavaScriptを使用してクライアント側の画像サイズを変更する

JavaScriptを使用してクライアント側の画像のサイズを変更する方法を探しています(幅と高さを変更するだけでなく、実際にサイズを変更します)。
Flashで実行できることはわかっていますが、可能であれば回避したいと思います。

ウェブ上のどこかにオープンソースのアルゴリズムはありますか?

141
geraud

これを行う要点は次のとおりです。 https://Gist.github.com/dcollien/312bce1270a5f511bf4a

(es6バージョン、およびスクリプトタグに含めることができる.jsバージョン)

次のように使用できます。

<input type="file" id="select">
<img id="preview">
<script>
document.getElementById('select').onchange = function(evt) {
    ImageTools.resize(this.files[0], {
        width: 320, // maximum width
        height: 240 // maximum height
    }, function(blob, didItResize) {
        // didItResize will be true if it managed to resize it, otherwise false (and will return the original file as 'blob')
        document.getElementById('preview').src = window.URL.createObjectURL(blob);
        // you can also now upload this blob using an XHR.
    });
};
</script>

私が管理できる限り多くのブラウザで動作することを確認するためのサポート検出とポリフィルの束が含まれています。

(GIF画像も無視します-アニメーション化されている場合)

98
dcollien

これに対する答えはイエスです-HTML 5では、canvas要素を使用してクライアント側で画像のサイズを変更できます。新しいデータを取得してサーバーに送信することもできます。このチュートリアルをご覧ください:

http://hacks.mozilla.org/2011/01/how-to-develop-a-html5-image-uploader/

58
Jeremy Usher

アップロードする前にサイズを変更していた場合、私はこれを見つけました http://www.plupload.com/

あらゆる想像可能な方法ですべての魔法を実行します。

残念ながら、HTML5のサイズ変更はMozillaブラウザーでのみサポートされていますが、他のブラウザーをFlashおよびSilverlightにリダイレクトできます。

試したところ、Androidで動作しました!

フラッシュで http://swfupload.org/ を使用していました。非常にうまく機能しますが、サイズ変更サイズは非常に小さいです。 (制限を思い出せません)、フラッシュが利用できないときにhtml4に戻りません。

12
ignacio

http://nodeca.github.io/pica/demo/

最新のブラウザでは、キャンバスを使用して画像データをロード/保存できます。ただし、クライアントで画像のサイズを変更する場合は、いくつかの点に留意する必要があります。

  1. チャンネルごとに8ビットしかありません(jpegのダイナミックレンジは約12ビットです)。プロの写真をアップロードしなくても問題ありません。
  2. サイズ変更アルゴリズムに注意してください。ほとんどのクライアント側のリサイザーは簡単な計算を使用しますが、結果は予想よりも悪くなります。
  3. 縮小した画像をシャープにする必要がある場合があります。
  4. 元のメタデータ(exifおよびその他)を再利用する場合は、カラープロファイル情報を削除することを忘れないでください。キャンバスに画像を読み込むときに適用されるためです。
9
Vitaly

おそらく、canvasタグを使用します(ただし、ポータブルではありません)。キャンバスで画像を回転させる方法についてのブログがあります here 、回転できるならサイズを変更できると思います。たぶんそれは出発点になります。

there も参照してください。

6
David V.

サーバーに画像をアップロードする前に、クライアント側の画像処理にjavascript画像処理フレームワークを使用できます。

以下では MarvinJ を使用して、次のページの例に基づいて実行可能なコードを作成しました。 "サーバーにアップロードする前にクライアント側で画像を処理する"

基本的に、メソッドMarvin.scale(...)を使用して画像のサイズを変更します。次に、画像をblobとしてアップロードします(メソッドimage.toBlob()を使用)。サーバーは、受信した画像のURLを提供して応答します。

/***********************************************
 * GLOBAL VARS
 **********************************************/
var image = new MarvinImage();

/***********************************************
 * FILE CHOOSER AND UPLOAD
 **********************************************/
 $('#fileUpload').change(function (event) {
        form = new FormData();
        form.append('name', event.target.files[0].name);
        
        reader = new FileReader();
        reader.readAsDataURL(event.target.files[0]);
        
        reader.onload = function(){
                image.load(reader.result, imageLoaded);
        };
        
});

function resizeAndSendToServer(){
  $("#divServerResponse").html("uploading...");
        $.ajax({
                method: 'POST',
                url: 'https://www.marvinj.org/backoffice/imageUpload.php',
                data: form,
                enctype: 'multipart/form-data',
                contentType: false,
                processData: false,
                
           
                success: function (resp) {
       $("#divServerResponse").html("SERVER RESPONSE (NEW IMAGE):<br/><img src='"+resp+"' style='max-width:400px'></img>");
                },
                error: function (data) {
                        console.log("error:"+error);
                        console.log(data);
                },
                
        });
};

/***********************************************
 * IMAGE MANIPULATION
 **********************************************/
function imageLoaded(){
  Marvin.scale(image.clone(), image, 120);
  form.append("blob", image.toBlob());
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.marvinj.org/releases/marvinj-0.8.js"></script>
<form id="form" action='/backoffice/imageUpload.php' style='margin:auto;' method='post' enctype='multipart/form-data'>
                                <input type='file' id='fileUpload' class='upload' name='userfile'/>
</form><br/>
<button type="button" onclick="resizeAndSendToServer()">Resize and Send to Server</button><br/><br/>
<div id="divServerResponse">
</div>

はい、最新のブラウザではこれは完全に実行可能です。キャンバスの変更を何回も実行したバイナリファイルとしてファイルをアップロードするという点までは実行可能です。

http://jsfiddle.net/bo40drmv/

(この回答は、受け入れられた回答の改善です here

PHPの結果送信をキャッチするプロセスを覚えておいてください:

//File destination
$destination = "/folder/cropped_image.png";
//Get uploaded image file it's temporary name
$image_tmp_name = $_FILES["cropped_image"]["tmp_name"][0];
//Move temporary file to final destination
move_uploaded_file($image_tmp_name, $destination);

Vitalyのポイントが気になる場合は、作業中のjfiddleでトリミングとサイズ変更を試してください。

2
Tatarize