スタートページJavascriptCANVASFile API

ローカル画像ファイルのCANVAS表示

単一のローカル画像ファイルをダイアログボックスで選択し、HTMLで記述した<canvas>に表示します。
・サーバ側の画像ファイルのCANVAS表示に関しては「画像ファイルのCANVAS表示」
・ローカル画像ファイルのダイアログボックス選択に関しては「ローカルファイルの内容表示」(FileReader)
を参照してください。


ローカル画像ファイルのサイズに合わせてCANVASのサイズを変更

下のボタンをクリックするとダイアログボックスが開きます。一つの画像ファイルをクリックすると、灰色のcanvas位置に画像ファイルが表示されます。画像のサイズに合わせれてcanvasのサイズが変わります。

<script>
function 関数1(files, CANVAS名) {        // ア 
    var canvas = document.getElementById(CANVAS名);  // イ canvasの定義
    var ctx = canvas.getContext('2d');          // ウ 
    var reader = new FileReader();              // エ ローカルファイルの処理
    reader.onload = function(event) {           // オ ローカルファイルを読込後処理
        var 画像 = new Image();                 // カ  画像ファイルの処理
        画像.onload = function() {              // キ   画像ファイル読込後の処理
            canvas.width  = 画像.naturalWidth;  // ク     naturalWidthは画像の元のサイズ
            canvas.height = 画像.naturalHeight; // ケ     canvas.widthはcanvasのサイズ
            ctx.drawImage(画像, 0, 0);          // コ     画像をcanvasに表示
        }                                       // サ 
        画像.src = event.target.result;         // シ   画像を読み込む 
    }                                           // ス 
    reader.readAsDataURL(files[0]);             // セ ローカルファイルを読み込む  

}
</script>

<input type="file" onChange="関数1(this.files, 'canvas1')"></input><br>  // ソ ダイアログボックスで選択
<canvas id="canvas1"></canvas>                                            // タ canvasの記述

厳密な説明には「非同期処理」や「コントラクタ」の概念が前提になりますが、ここではむしろイメージ的な説明をします。

  • ソのtype="file"でダイアログボックスが開きローカル画像ファイルを選択します。this.filesは「選択したファイルの情報」の意味です。選択するとこのボタンの情報が変わる(onChange)のでアが呼び出されます。
  • 「選択したファイルの情報」はアのfilesで受け取ります。複数ファイル選択が許されているのでfilesは配列になります。
    ここでは一つのファイルを前提にしているので、セのようにfiles[0]とします。
  • エのFileReaderとは、「ローカルファイルの内容をWebページに取り込む」機能であり、ここではそれをreaderと呼ぶことを意味しています。エでは取り込む処理はしていません。
  • セで実際の取込処理をします。ソにより選択したローカルファイルfiles[0]のURL(DataURL)として取り込みます。
  • 取り込みのキッカケになるのは、ソでのonChangeイベントの発生です。オは、そのイベントをeventと定義して、eventが発生したらカ~シの処理を行えという意味です。
    (セをオの前においてはいけません。オで読込後の処理を予約してセが終了(onload)するのを待つのです。)
  • オの段階では、scriptはファイルが画像であることはわかりません。私たちは画像であることを知っているので、画像としての処理を行います。
  • シのevent.target.resultは、eventによりFileReaderで読み込んだ結果を「画像.src」とする、すなわち、&li;img src=files[0]>のような意味になります。
  • キにより、画像ファイルが読み込まれた後の処理が行われます。
    (シをキの前に記述してはいけないのは、セとオの関係と同じです)

CANVASのサイズに合わせてローカル画像ファイルを圧縮

例えば、<canvas width="400" height="300"> としたとき、ローカル画像ファイルを縦横比を保ちつつ、CANVASのサイズに収まるように圧縮・拡大します。canvasの下あるいは右に余白ができます。

変更するのは赤色の部分です。ここで上の圧縮・拡大の処理が行われます(灰色の部分は「空白」を示すだけであり、本質的なものではありません)。

<script>
function 関数2(files, CANVAS名) {
    // canvasの定義
    var canvas = document.getElementById(CANVAS名);
    var ctx = canvas.getContext('2d');
    var reader = new FileReader();
    reader.onload = function(event) {
        var 画像 = new Image();
        画像.onload = function() {
                                            // 画像の圧縮
            var canvas幅 = canvas.width;
            var canvas高 = canvas.height;
            var 画像幅 = 画像.naturalWidth;      // naturalWidthは元の画像の幅
            var 画像高 = 画像.naturalHeight;
            var canvas縦横比 = canvas高 / canvas幅;
            var 縦横比 = 画像高 / 画像幅;
            if (縦横比 <= canvas縦横比) {        // 縦横比≦canvas縦横比→横長→canvasの横幅がネックに
                var 圧縮後画像幅 = canvas幅;
                var 圧縮率 = canvas幅 / 画像幅;
                var 圧縮後画像高 = 圧縮率 * 画像高;
            }
            else {                              // 縦長のとき
                圧縮後画像高 = canvas高;
                圧縮率 = canvas高 / 画像高;
                圧縮後画像幅 = 圧縮率 * 画像幅;
            }
            // canvas全体をgrayにする(本質的ではない)
            ctx.fillStyle = 'gray';
            ctx.fillRect(0, 0, canvas幅, canvas高);
            // 画像を圧縮してcanvas表示
            ctx.drawImage(画像, 0, 0, 圧縮後画像幅, 圧縮後画像高);
        }
        画像.src = event.target.result;
    }
    reader.readAsDataURL(files[0]);
}
</script>

<input type="file" onChange="関数2(this.files, 'canvas2')"></input><br>
<canvas id="canvas2" width="400" height="300"></canvas>