【JavaScript入門】画像の描画

 Canvas 2D API では、外部画像・生成済み <img> 要素・別の Canvas などあらゆるビットマップを drawImage() で 1 行描画できます。しかも トリミング・リサイズ を同時に行えるため、スプライトアニメーションやサムネイル生成、レイヤ合成が簡単です。ここでは画像ソースの用意から drawImage 3 種オーバーロードの使い分けまでを一気に把握し、読み込みの非同期性にも正しく対処する方法を学びます。

1.描画前に知っておくプロセス

ステップ要点API / サンプル
画像取得<img> タグ・new Image()・他 Canvas などを “ソース” にするconst img = new Image();
非同期待機画像はネットワーク/ディスク読み込みが完了して初めて pixel へアクセス可img.onload = () => { ... }
描画drawImage() を呼び出し Canvas バッファへ転送ctx.drawImage(img, x, y);

Tips: 画像が巨大な場合、一旦オフスクリーン Canvas に縮小描画し、そこからコピーするとパフォーマンス&画質の両立が容易です。

2.drawImage オーバーロード一覧

シグネチャ用途
drawImage(image, dx, dy)原寸 でそのまま描く
drawImage(image, dx, dy, dw, dh)指定領域に リサイズ 描画
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)トリミング(切り取り)+リサイズ同時

パラメータ名の意味

  • s* : source(画像内で切り出す範囲)
  • d* : destination(Canvas 上で貼り付ける位置と大きさ)

3.サンプルプログラム

  • ファイル名: image_draw_demo.html
  • 絵画の画像ファイル: 下図からダウンロードできます。

PNGファイルのダウンロードは、ここ「checker.png」からできます。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>🖼️ Canvas Image Demo</title>
<style>
  body  {font-family:"Segoe UI",sans-serif;background:#f8fbff;text-align:center;margin:2rem}
  h1    {font-size:1.8rem;margin-bottom:1rem}
  canvas{border:1px solid #666;border-radius:6px;background:url(./checker.png)}
  #info {margin-top:.8rem;color:#00695c;font-weight:bold}
</style>
</head>
<body>
  <h1>🖼️ 画像の描画デモ</h1>
  <canvas id="stage" width="600" height="360"></canvas>
  <p id="info">画像の一部をトリミングして描画しました!</p>

<script>
(() => {
  const ctx = document.getElementById('stage').getContext('2d');

  // ① 画像ソースを生成
  const img = new Image();
  img.src = './drawing-image03.png';

  // ② 読み込み完了後に描画
  img.onload = () => {
    /* A. 原寸そのまま(左上 180x120 の縮小表示)*/
    ctx.drawImage(img, 20, 20, 180, 120);

    /* B. 画像中央をトリミングし拡大 */
    const sx = img.width  * 0.25;   // 元画像の 25% 位置
    const sy = img.height * 0.25;
    const sw = img.width  * 0.5;    // 幅・高さとも 50% 抜き出し
    const sh = img.height * 0.5;
    ctx.drawImage(img, sx, sy, sw, sh, 240, 20, 340, 320);

    /* C. 日本語メッセージ */
    ctx.font = 'bold 28px sans-serif';
    ctx.fillStyle = '#ffffff';
    ctx.strokeStyle = '#000000';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'bottom';
    ctx.strokeText('トリミング&リサイズ完了', 410, 350);
    ctx.fillText('トリミング&リサイズ完了', 410, 350);
  };

  // ③ エラーハンドリング(オプション)
  img.onerror = () => {
    ctx.font = '20px sans-serif';
    ctx.fillStyle = '#d32f2f';
    ctx.fillText('画像の読み込みに失敗しました…', 300, 180);
  };
})();
</script>
</body>
</html>

ブラウザの出力例

  1. 左上に 180×120 px へリサイズされた全体プレビュー
  2. 右側大きく切り出された “中央 50%” 領域(拡大表示)
  3. 下部に「トリミング&リサイズ完了」という日本語メッセージが白塗り+黒線で視認性高くレンダリング

プログラム解説

内容解説
27A : drawImage(img,20,20,180,120)第 2 シグネチャでリサイズのみ
31B : 第 3 シグネチャ元画像の中央半分を抜き出し → 340×320 px に拡大
39メッセージ描画fillText + strokeText で縁取りし背景と同化しないように

まとめ

  • 画像ソースは <img> でも new Image() でも OK。読み込み完了イベント 待ちは必須。
  • drawImage原寸・リサイズ・トリミング+リサイズ の 3 形態。パラメータが増えるほど細かく制御できる。
  • 複数 drawImage を 1 フレームで呼ぶことでゲームのスプライトアニメやサムネイル一覧も高速生成可能。

 これらの基本をマスターすれば、フォトエディタ風アプリやキャンバスゲームの画像管理がぐっと快適になります。