PR

HTML+JavaScriptだけでブラウザに図形描画(3) - Canvas API -

2012年10月11日(木)
山田 祥寛(YAMADA, Yoshihiro)

TIPS 030:画像を拡大/回転/変形して表示する

Canvas APIでは、scale(拡大縮小)、rotate(回転)、translate(移動)、transform(変形)など、図形を変形/加工するためのさまざまなメソッドが用意されています。以下では、これらのメソッドを利用した例を見てみましょう。

[リスト03]画像を拡大/回転/変形するコード(transform.html)

window.addEventListener('DOMContentLoaded',
  function() {
    if (HTMLCanvasElement) {
      var cv = document.querySelector('#cv');
      var c = cv.getContext('2d');
      // 初期状態のコンテキストをあらかじめ保存
      for (var i = 0; i < 3; i++) { c.save(); }
      // 画像を準備
      var img = new Image();
      img.src = 'wings.jpg';
      img.addEventListener('load', function(e) {
        // 半分に縮小して描画
        c.scale(0.5, 0.5);
        c.drawImage(img, 0, 0);
 
        // 30°回転したものを描画
        c.restore();
        c.rotate(30 * Math.PI / 180);
        c.drawImage(img, 50, 50);
 
        // (180, 200)ずらした上で描画
        c.restore();
        c.translate(180, 200);
        c.drawImage(img, 0, 0);
 
        // 変形マトリクスで変換した上で描画
        c.restore();
        c.transform(1, 1, 1, -1, 0, 0);
        c.drawImage(img, 70, 100);
      });
    }
  }
);
図3:画像を加工した上で貼り付け(クリックで拡大)

それぞれの構文を見てみましょう。

[構文]scale/rotate/translate/transformメソッド

  • scale(横倍率, 縦倍率) … 拡大/縮小
  • rotate(角度) … 回転
  • translate(水平方向, 垂直方向) … 移動
  • transform(m11, m12, m21, m22, dx, dy) … 変形

transformメソッドは、scale/rotate/translateメソッドをひとつにまとめたメソッドと言っても良いでしょう。以下のような変換マトリクスを使って、図形を変形させます。

図4:図形を変形させる変換マトリクス(クリックで拡大)

単純な拡大/縮小、回転、移動には専用のメソッドの方が簡単ですが、より複雑な座標変換には、transformメソッドを利用します。以下に簡単な利用パターンをまとめます。

表2:transformメソッドの利用例

概要
transform(x, 0, 0, y, 0, 0) 横x倍、縦y倍に拡大
transform(Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0) r(ラジアン)だけ回転
transform(1, 0, 0, 1, x, y) 水平方向にx、垂直方向にyだけ移動

なお、transformメソッドは、実行都度に変換マトリクスを累積していきます。

もしも新たに変換マトリクスを適用したい(または、状態を初期化したい)という場合には、setTransformメソッドを利用してください。setTransformメソッドは、変換マトリクスを累積するのではなく、新たに設定し直します。

サンプルでは、キャンバス状態の初期化にrestoreメソッドを利用していますが、代わりにsetTransformメソッドを使って、以下のように書いても良いでしょう。

  c.setTransform(1, 0, 0, 1, 0, 0);

TIPS 031:キャンバス上の図形の一部を切り出す/貼り付ける

getImageDataメソッドを利用すると、キャンバス上の特定の領域を切り出すことができます。また、切り出した画像はputImageDataメソッドを利用することで、同じキャンバス(または異なるキャンバス)に貼り付けることができます。

以下は、上のキャンバスに描画した画像の一部を切り出し、下のキャンバスに貼り付ける例です。

[リスト04]キャンバスに描画された図形の一部をコピーするコード(imageData.html)

window.addEventListener('DOMContentLoaded',
  function() {
    if (HTMLCanvasElement) {
      // 上下キャンバスのコンテキストを準備
      var cv = document.querySelector('#cv');
      var c = cv.getContext('2d');
      var cv2 = document.querySelector('#cv2');
      var c2 = cv2.getContext('2d');
      // 上のキャンバスに画像を貼り付け
      var img = new Image();
      img.src = 'rin.jpg';
      img.addEventListener('load', function(e) {
        c.drawImage(img, 0, 0, 400, 300);
        // 座標(180, 150)から150×150の大きさで画像を切り出し
        var d  = c.getImageData(180, 150, 150, 150);
        // 下のキャンバス(50, 50)の位置に切り出した画像を貼り付け
        c2.putImageData(d, 50, 50);
      });
    }
  }
);
...中略...
<canvas id="cv" width="400" height="300">
Canvas機能に対応したブラウザでアクセスしてください。
</canvas><br />
<canvas id="cv2" width="400" height="300">
Canvas機能に対応したブラウザでアクセスしてください。
</canvas>
図5:上キャンバスの一部を下キャンバスにコピー(クリックで拡大)

getImageDataメソッドの構文は、以下のとおりです。

[構文]getImageDataメソッド

  • getImageData(x, y, width, height)

これで座標(x, y)を基点としてwidth×heightのサイズで画像データを取得しなさいという意味になります。getImageDataメソッドの戻り値は、ImageDataオブジェクトです。

ImageDataオブジェクトは、そのままputImageDataメソッドに渡せます。

[構文]putImageDataメソッド

  • putImageData(ImageDataオブジェクト, x, y)

指定されたImageDataオブジェクトを、座標(x, y)に貼り付けます。

サンプルでは、ImageDataオブジェクトをそのまま貼り付けているだけですが、ImageDataオブジェクトはピクセルデータを配列として保持しています。

図6:画像の色味や透明度を変化させて貼り付けることができる(クリックで拡大)

ひとつのピクセルを赤、緑、青、不透明度という4つの要素で表現しているわけです。これらの値を操作することで、色味や透明度を変化させた上で、画像を貼り付けるということもできるでしょう。

Think IT会員限定特典
  • Canvas APIを使ってブラウザに図形を描画するサンプル(3)

著者
山田 祥寛(YAMADA, Yoshihiro)
WINGSプロジェクト

有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表:山田祥寛)。おもな活動は、Web開発分野の書籍/雑誌/Web記事の執筆。ほかに海外記事の翻訳、講演なども幅広く手がける。2011年3月時点での登録メンバは36名で、現在もプロジェクトメンバーを募集中。

連載バックナンバー

Think IT会員サービス無料登録受付中

Think ITでは、より付加価値の高いコンテンツを会員サービスとして提供しています。会員登録を済ませてThink ITのWebサイトにログインすることでさまざまな限定特典を入手できるようになります。

Think IT会員サービスの概要とメリットをチェック

他にもこの記事が読まれています

HTML+JavaScriptだけでブラウザに図形描画(3) - Canvas API - | Think IT(シンクイット)

Think IT(シンクイット)

サイトに予期せぬエラーが起こりました。しばらくたってから再度お試しください。