60

HTML5 File API で開いた画像をキャンバスに描画したいと考えています。

handleFiles(e)メソッドでは、 File にアクセスできますが、をe.target.files[0]使用してその画像を直接描画することはできませんdrawImage。HTML5 キャンバスでファイル API から画像を描画するにはどうすればよいですか?

これが私が使用したコードです:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script>
window.onload = function() {
    var input = document.getElementById('input');
    input.addEventListener('change', handleFiles);
}

function handleFiles(e) {
    var ctx = document.getElementById('canvas').getContext('2d');
    ctx.drawImage(e.target.files[0], 20,20);
    alert('the image is drawn');
}
</script>
</head>
<body>
<h1>Test</h1>
<input type="file" id="input"/>
<canvas width="400" height="300" id="canvas"/>
</body>
</html>
4

3 に答える 3

90

File画像ではないインスタンスがあります。

画像を取得するには、 を使用しますnew Image()。はsrc、選択した を参照する URL である必要がありますFileURL.createObjectURLを参照する URL を取得するために使用できますBlob(aFileも a ですBlob): http://jsfiddle.net/t7mv6/86/

var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image;
img.onload = function() {
    ctx.drawImage(img, 20,20);
    alert('the image is drawn');
}
img.src = URL.createObjectURL(e.target.files[0]);

注:オブジェクトの URL を使い終わったら必ず取り消してください。そうしないと、メモリ リークが発生します。あまりクレイジーなことをしていない場合はURL.revokeObjectURL(img.src)img.onload関数に a を貼り付けることができます。

参考文献:

于 2011-07-21T12:29:03.017 に答える
14

実際の例

function handleFiles(e) {
    var ctx = document.getElementById('canvas').getContext('2d');
    var url = URL.createObjectURL(e.target.files[0]);
    var img = new Image();
    img.onload = function() {
        ctx.drawImage(img, 20, 20);    
    }
    img.src = url;   
}

window.URL.createObjectUrlドキュメント

FileReader代わりに を使用してオブジェクト URL を作成することもできます。

FileReaderブラウザ サポートはわずかに優れています。

このFileReaderアプローチは FF6 / Chrome で機能します。Img.srcただし、 a への設定Blobが有効でクロスブラウザーであるかどうかはわかりません。

オブジェクトの URL を作成するのが正しい方法です。

編集:

コメントのサポートで述べたように、window.URLオフラインは FF6/Chrome では利用できないようです。

于 2011-07-21T12:29:43.273 に答える
4

これは完全な例(Fiddle)です( RaynosFileReaderが述べたように、ブラウザのサポートが向上しています)。この例では、Canvas もイメージに合わせてスケーリングします。

実際の例では、フォームが爆発しないように画像を最大にスケーリングする場合があります;-)。スケーリング (Fiddle)の例を次に示します。

var URL = window.webkitURL || window.URL;

window.onload = function() {
    var input = document.getElementById('input');
    input.addEventListener('change', handleFiles, false);
    
    // set original canvas dimensions as max
    var canvas = document.getElementById('canvas');
    canvas.dataMaxWidth = canvas.width;
    canvas.dataMaxHeight = canvas.height;
}

function handleFiles(e) {
    var ctx = document.getElementById('canvas').getContext('2d');
    var reader  = new FileReader();
    var file = e.target.files[0];
    // load to image to get it's width/height
    var img = new Image();
    img.onload = function() {
        // setup scaled dimensions
        var scaled = getScaledDim(img, ctx.canvas.dataMaxWidth, ctx.canvas.dataMaxHeight);
        // scale canvas to image
        ctx.canvas.width = scaled.width;
        ctx.canvas.height = scaled.height;
        // draw image
        ctx.drawImage(img, 0, 0
            , ctx.canvas.width, ctx.canvas.height
        );
    }
    // this is to setup loading the image
    reader.onloadend = function () {
        img.src = reader.result;
    }
    // this is to read the file
    reader.readAsDataURL(file);
}

// returns scaled dimensions object
function getScaledDim(img, maxWidth, maxHeight) {
    var scaled = {
        ratio: img.width / img.height,
        width: img.width,
        height: img.height
    }
    if (scaled.width > maxWidth) {
        scaled.width = maxWidth;
        scaled.height = scaled.width / scaled.ratio;
    }
    if (scaled.height > maxHeight) {
        scaled.height = maxHeight;
        scaled.width = scaled.height / scaled.ratio;
    }
    return scaled;
}
canvas {
    border:1px solid black
}
<input type="file" id="input"/>
<div>
    <canvas width="400" height="300" id="canvas"/>
</div>

于 2015-10-13T21:05:06.557 に答える