Chapter 79

モザイク

miku
miku
2021.11.19に更新
このチャプターの目次

実行例


解説

3*3 のような一定範囲のピクセルを対象に、RGBごとに平均化した値を設定し直す。

上記だと、 (171 + 21 + 66 + 84 + 180 + 3 + 205 + 78 + 168) / 9 ≒ 108 を 3x3 のピクセルに再代入する。

範囲計算の際にインデックスがはみ出る場合はその部分の計算は行わない。

上記だと、 (200 + 47 + 55 + 251 + 53 + 172) / 6 ≒ 129 を 2x3 のピクセルに再代入する。

コード例

const range = 10;
let img;

function preload() {
  img = loadImage("./0.png");
}

function setup() {
  createCanvas(img.width, img.height);
  img.loadPixels();

  for (let y = 0; y < img.height; y += range) {
    for (let x = 0; x < img.width; x += range) {
      let tr = 0;
      let tg = 0;
      let tb = 0;

      let count = 0;

      for (let yy = 0; yy < range; yy++) {
        for (let xx = 0; xx < range; xx++) {
          const ty = y + yy;
          const tx = x + xx;
          if (ty < img.height && tx < img.width) {
            const pixel = getPixel(tx, ty);
            const r = red(pixel);
            const g = green(pixel);
            const b = blue(pixel);
            tr += r;
            tg += g;
            tb += b;
            count++;
          }
        }
      }

      tr /= count;
      tg /= count;
      tb /= count;

      for (let yy = 0; yy < range; yy++) {
        for (let xx = 0; xx < range; xx++) {
          const ty = y + yy;
          const tx = x + xx;
          if (ty < img.height && tx < img.width) {
            setPixel(tx, ty, [tr, tg, tb]);
          }
        }
      }
    }
  }

  img.updatePixels();
  image(img, 0, 0);
}

function getPixel(x, y) {
  const i = (y * img.width + x) * 4;
  return [
    img.pixels[i],
    img.pixels[i + 1],
    img.pixels[i + 2],
    img.pixels[i + 3],
  ];
}

function setPixel(x, y, pixel) {
  const i = (y * img.width + x) * 4;
  img.pixels[i + 0] = pixel[0];
  img.pixels[i + 1] = pixel[1];
  img.pixels[i + 2] = pixel[2];
}