虎の穴開発室ブログ

虎の穴ラボ株式会社所属のエンジニアが書く技術ブログです

MENU

画像から取得したImageData オブジェクトで花火を描画してみた

本記事は2023 夏のブログ連載企画 17 日目の記事です。 昨日 7 月 17 日は、おっくんさんの「レンガ 🧱の積み方をbabylon.js と 物理エンジン(Havok)で シミュレーション!」でした。

明日は、godan さんの「Lottieでサイトおしゃれにしたい!」です。

メイドちゃんが LGTM👍 してくれる花火🎆を打ち上げたい!

とらラボでは可愛いメイドちゃんイラストを公開しています。

今回は LGTM のイラストを用いて、可愛くて元気をもらえる花火を打ち上げてみましょう。

yumenosora.co.jp

作ったもの

どんなことしている?

ざっくり 3 STEP で画像から花火を作成しています。

  1. 画像からImageData オブジェクトを取得
  2. ImageData オブジェクトから花火の星を作成
  3. 花火の星に座標移動のアニメーションをつける

画像から ImageData オブジェクトを取得

画像をcanvasに描画しgetImageData () メソッドを用いることで、各ピクセルの色(RGBA)を表す ImageData オブジェクトを取得できます。

developer.mozilla.org

import lgtmImg from '@/assets/images/28_LGTM.png';

const getImageData = () => {
  // canvas要素を作成
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  if (!ctx) return;

  // 画像を読み込み、canvasに描画
  const img = new Image();
  img.onload = () => {
    ctx.drawImage(img, 0, 0);

    // ImageDataオブジェクトを取得
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  };
  img.src = lgtmImg;
};

実際のデータは下記の通り。

ImageData {data: Uint8ClampedArray(1254400), width: 560, height: 560, colorSpace: 'srgb'}

data プロパティには各ピクセルの RGBA 値を表す一次元配列が格納されます。配列の長さは height(560) × width(560) × RGBA(4) = 1254400 となっています。

ImageData オブジェクトから花火の星を作成

ここで花火の星とは、花火を構成する粒のひとつを指し、それぞれ色・座標・半径を持たせるようにします。

処理はシンプルで「ImageData オブジェクトdata プロパティから、一定の間隔ごとにピクセルの色と座標を取得」となります。

import { Star } from '@/types/Star.types';

export const generateStars = (imageData: ImageData, interval: number, radius: number): Star[] => {
  const stars: Star[] = [];
  const data = imageData.data;

  // 一定の間隔ごとにピクセルの色と座標を取得
  for (let y = 0; y <= imageData.height; y += interval) {
    for (let x = 0; x <= imageData.width; x += interval) {

      // ピクセルの色情報を取得
      // 画像のピクセルは1次元配列で管理されているため、
      // 4つの要素を1つのピクセルとして扱う
      const index = (y * imageData.width + x) * 4;
      const red = data[index];
      const green = data[index + 1];
      const blue = data[index + 2];
      const alpha = data[index + 3];

      stars.push({
        color: { red, green, blue, alpha },
        x,
        y,
        radius,
      });
    }
  }

  return stars;
};

花火の星を作成した後は、間隔や半径を調整し花火らしく見えるようにします。

花火の星に座標移動のアニメーションをつける

最後にいい感じに打ち上がるアニメーションのあとに、花火の星が中心から各座標へ向かうようアニメーションをつければ完成です!(力技なのでコードは割愛)

まとめ

ImageDataを用いて画像の色情報を取得し、花火を描画してみました。ImadeDataは画像のグレースケール化、ズーム、アンチエイリアシングといった処理でも役立つのでぜひ活用してみてください!

developer.mozilla.org

採用情報

虎の穴ラボでは一緒に働く仲間を募集中です!
この記事を読んで、興味を持っていただけた方はぜひ弊社の採用情報をご覧ください。
yumenosora.co.jp