有没有办法将冒泡排序像素恢复为原始图像?

Is there a way to bubble sort pixels back to the original image?

感谢阅读本文。我正在尝试修改 sketch.js provided by the author of this 像素排序教程。

我想知道将每个像素的原始位置存储在附加纹理中以便使图像能够排序回原始位置的最佳方法是什么?

到目前为止,我的目标是在绘图函数中放置 2 个条件语句,以便在某个时间点(或迭代次数)像素开始冒泡排序回到原始图像,然后才排序再次备份。

事情可能是正确的

  1. 更改比较符号(即从大变为负)
  2. 在两个语句中复制 .loadPixels() 和 .updatePixels()。

我不太确定的事情

  1. 反转 else 语句中的 for 循环
  2. 将像素索引从 (j, i + 1) 更改为 (j, i - 1)

我还没有想通的事情

  1. 原始图像重新组合后重新排序的方法

let panel;
let counter = 0;
const sc = 2;
const panelW = 25;
const panelH = 15;
const frameW = 20;

function preload() {
  panel = loadImage("https://www.paulwheeler.us/files/Burano-island-Venice.jpg");
}

function setup() {
  createCanvas(
    sc * (panel.width + 2 * frameW),
    sc * (panel.height + 2 * frameW)
  );
  pixelDensity(1);
}

function draw() {

  if (counter < 3200000) {
    panel.loadPixels();
    for (let i = 0; i < panel.height - 1; i++) {
      for (let j = 0; j < panel.width; j++) {
        counter = counter + 1;
        if (
          hue(fGetPanelPixel(j, i)) >
          hue(fGetPanelPixel(j, i + 1))
        ) {
          let hold = fGetPanelPixel(j, i + 1);
          fSetPanelPixel(j, i + 1, fGetPanelPixel(j, i));
          fSetPanelPixel(j, i, hold);
        }
      }
    }
    panel.updatePixels();

  } else {
    console.log("now backwards...");
    panel.loadPixels();

    for (let i = panel.height - 1; i > 0; i--) {
      for (let j = panel.width - 1; j > 0; j--) {
        if (
          hue(fGetPanelPixel(j, i)) <
          hue(fGetPanelPixel(j, i - 1))
        ) {
          let hold = fGetPanelPixel(j, i - 1);
          fSetPanelPixel(j, i - 1, fGetPanelPixel(j, i));
          fSetPanelPixel(j, i, hold);
        }
      }
    }
    panel.updatePixels();
  }

  image(panel, sc * frameW, sc * frameW, sc * panel.width, sc * panel.height);
}

function fGetPanelPixel(x, y) {
  const index = 4 * (y * panel.width + x);
  return [
    panel.pixels[index],
    panel.pixels[index + 1],
    panel.pixels[index + 2],
  ];
}

function fSetPanelPixel(x, y, c) {
  const index = 4 * (y * panel.width + x);
  panel.pixels[index] = c[0];
  panel.pixels[index + 1] = c[1];
  panel.pixels[index + 2] = c[2];
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

上面的代码在似乎向后排序的情况下有效,但视觉效果很快就会卡住,而无需重新合成原始图像。 由于我是一个完全的新手,非常感谢任何见解,干杯!

为了反转排序,将像素放回原来的位置,您需要排序不是基于色相,而是基于每个像素的原始位置。这意味着您需要一个单独的数据结构来跟踪每个像素的来源:

let panel;
let counter = 0;
const sc = 2;
const panelW = 25;
const panelH = 15;
const frameW = 20;

let pixelOrigin = [];

function preload() {
  panel = loadImage("https://www.paulwheeler.us/files/Burano-island-Venice.jpg");
}

function setup() {
  createCanvas(
    sc * (panel.width + 2 * frameW),
    sc * (panel.height + 2 * frameW)
  );
  pixelDensity(1);
  for (let j = 0; j < panel.width; j++) {
    pixelOrigin[j] = [];
    for (let i = 0; i < panel.height; i++) {
      pixelOrigin[j][i] = i;
    }
  }
}

function draw() {
  if (counter < 3200000) {
    panel.loadPixels();
    for (let i = 0; i < panel.height - 1; i++) {
      for (let j = 0; j < panel.width; j++) {
        counter = counter + 1;
        if (
          hue(fGetPanelPixel(j, i)) >
          hue(fGetPanelPixel(j, i + 1))
        ) {
          let hold = fGetPanelPixel(j, i + 1);
          fSetPanelPixel(j, i + 1, fGetPanelPixel(j, i));
          fSetPanelPixel(j, i, hold);

          // Also swap origins
          let tmp = pixelOrigin[j][i + 1];
          pixelOrigin[j][i + 1] = pixelOrigin[j][i];
          pixelOrigin[j][i] = tmp;
        }
      }
    }
    panel.updatePixels();

  } else {
    panel.loadPixels();
    for (let i = panel.height - 2; i >= 0; i--) {
      for (let j = 0; j < panel.width; j++) {
        if (pixelOrigin[j][i] > pixelOrigin[j][i + 1]) {
          let hold = fGetPanelPixel(j, i + 1);
          fSetPanelPixel(j, i + 1, fGetPanelPixel(j, i));
          fSetPanelPixel(j, i, hold);

          // Also swap origins
          let tmp = pixelOrigin[j][i + 1];
          pixelOrigin[j][i + 1] = pixelOrigin[j][i];
          pixelOrigin[j][i] = tmp;
        }
      }
    }
    panel.updatePixels();
  }

  image(panel, sc * frameW, sc * frameW, sc * panel.width, sc * panel.height);
}

function fGetPanelPixel(x, y) {
  const index = 4 * (y * panel.width + x);
  return [
    panel.pixels[index],
    panel.pixels[index + 1],
    panel.pixels[index + 2],
  ];
}

function fSetPanelPixel(x, y, c) {
  const index = 4 * (y * panel.width + x);
  panel.pixels[index] = c[0];
  panel.pixels[index + 1] = c[1];
  panel.pixels[index + 2] = c[2];
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>