1

グラフィックス オブジェクト (セットアップ中) で一連の円を事前にディザリングし、後でそれらを描画することにより、P5.js スケッチに Floyd-Steinberg ディザリングを実装しようとしています。

ただし、円の一部だけがディザリングされ、残りは正常に見えるという問題が発生し続けます。何が起こっているのか本当に困惑しているので、どんな提案も大歓迎です。

例

setup():

let circs;
function setup() {
  //...
  createCanvas(1000,1000);
  let size = 200;
  circs = [];
  circs.push({
    gfx: createGraphics(size, size),
    size: size,
    color: color(random(255))
  });
  for (let i = 0; i < circs.length; i++)
    dither(circs[i]);
  // ...
}

draw():

function draw() {
  if (!paused) {
    background(bg);
    drawShadow(4);  // just a call to the drawingContext shadow

    for (let i = 0; i < circs.length; i++) {
      push();
      translate(width / 2, height / 2);
      imageMode(CENTER);
      image(circs[i].gfx, 0, 0);
      pop();
    }
  }
}

floyd-steinberg - based on https://openprocessing.org/sketch/1192123

function index(x, y, g) {
  return (x + y * g.width) * 4;
}

function dither(g) {
  g.loadPixels();
  for (let y = 0; y < g.height - 1; y++) {
    for (let x = 1; x < g.width - 1; x++) {
      let oldr = g.pixels[index(x, y, g)];
      let oldg = g.pixels[index(x, y, g) + 1];
      let oldb = g.pixels[index(x, y, g) + 2];

      let factor = 1.0;
      let newr = round((factor * oldr) / 255) * (255 / factor);
      let newg = round((factor * oldg) / 255) * (255 / factor);
      let newb = round((factor * oldb) / 255) * (255 / factor);

      g.pixels[index(x, y, g)] = newr;
      g.pixels[index(x, y, g) + 1] = newg;
      g.pixels[index(x, y, g) + 2] = newb;

      g.pixels[index(x + 1, y, g)] += ((oldr - newr) * 7) / 16.0;
      g.pixels[index(x + 1, y, g) + 1] += ((oldr - newr) * 7) / 16.0;
      g.pixels[index(x + 1, y, g) + 2] += ((oldr - newr) * 7) / 16.0;

      g.pixels[index(x - 1, y + 1, g)] += ((oldr - newr) * 3) / 16.0;
      g.pixels[index(x - 1, y + 1, g) + 1] += ((oldr - newr) * 3) / 16.0;
      g.pixels[index(x - 1, y + 1, g) + 2] += ((oldr - newr) * 3) / 16.0;

      g.pixels[index(x, y + 1, g)] += ((oldr - newr) * 5) / 16.0;
      g.pixels[index(x, y + 1, g) + 1] += ((oldr - newr) * 5) / 16.0;
      g.pixels[index(x, y + 1, g) + 2] += ((oldr - newr) * 5) / 16.0;

      g.pixels[index(x + 1, y + 1, g)] += ((oldr - newr) * 1) / 16.0;
      g.pixels[index(x + 1, y + 1, g) + 1] += ((oldr - newr) * 1) / 16.0;
      g.pixels[index(x + 1, y + 1, g) + 2] += ((oldr - newr) * 1) / 16.0;
    }
  }
  g.updatePixels();
}

ディザリングアルゴリズムが高さと幅をループしてから更新する必要があるため、何が欠けているのかわかりませんが、何かが欠けていると思います。

4

1 に答える 1