📺

TVノイズ的なグリッチ表現をつくりたい【base64に変換してcanvasにマッピング】

2023/02/20に公開

完成イメージ

今回やりたいのはこういう感じの古いテレビみたいなのグリッチ表現です.
砂嵐的な表現はよく使われてると思いますが、こういう感じのはあまり見かけないような気がします.

まあ使い所はなかなか難しいですね笑

実装を担当したこちらのサイトで実装してみてるので、よかったらご覧ください〜
https://musashisuzuki.jp/

画像を選定する

今回はadobe stockで良い感じの画像を選定しました.
https://stock.adobe.com/jp/images/glitch-noise-static-television-vfx-pack-visual-video-effects-stripes-background-crt-tv-screen-no-signal-glitch-effect/455476393
https://stock.adobe.com/jp/images/abstract-background-with-copy-space-for-text-old-tv-scan-line-monitor-for-glitch-overlay/319681541
ただ、これだと背景色が一致しないので、背景色を一致させる必要がありました.

base64に変換する

そこで全ての画像をbase64に変換してcanvasにdrawImageして、getImageDataしておきます

glitchOBJ.ctx.drawImage(
         img,
         0,
         0,
         img.width,
         img.height,
         0,
         0,
         wWidth,
         wHeight
      );
imgData = glitchOBJ.ctx.getImageData(0, 0, wWidth, wHeight);

rgb値がそれぞれ50以下のalpha値を0にする

getImageDataしてきたdata情報はrgbaが格納された配列でかえってきます

ImageData.data property returns a Uint8ClampedArray that contains the ImageData object's pixel data. Data is stored as a one-dimensional array in the RGBA order, with integer values between 0 and 255
https://developer.mozilla.org/en-US/docs/Web/API/ImageData/data

for (let i = 0; i < dataLen; i += 4) {
         if (pix[i + 3] > 0) {
            const r = pix[i];
            const g = pix[i + 1];
            const b = pix[i + 2];
            if (r < 50 && g < 50 && b < 50) {
               pix[i + 3] = 0;
            }
         }
      }

画像データをcanvasにマッピングする

あとはロード判定とrAFの制限を仕込みつつframe毎にputImageDataで画像データを切り替えています.

const glitchLoop = (timestamp) => {
   if (limitFrames.isLimitFrames(timestamp) || glitchOBJ.isLoaded === false) {
      glitchOBJ.rAFID = requestAnimationFrame(glitchLoop);
      return;
   }
   if (glitchOBJ.frame >= glitchOBJ.imgArr.length - 1) {
      glitchOBJ.frame = 0;
   } else {
      glitchOBJ.frame++;
   }
   glitchOBJ.ctx.putImageData(glitchOBJ.glitchArr[glitchOBJ.frame], 0, 0);
   glitchOBJ.rAFID = requestAnimationFrame(glitchLoop);
};

Discussion