【问题标题】:Is there a way to bubble sort pixels back to the original image?有没有办法将像素冒泡排序回原始图像?
【发布时间】:2022-01-04 10:55:48
【问题描述】:

感谢您阅读本文。我正在尝试修改this像素排序教程作者提供的sketch.js

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

到目前为止,我的目标是在 draw 函数中放置 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];
}
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"&gt;&lt;/script&gt;

上面的代码可以正常工作,因为它看起来是向后排序的,但是视觉效果很快就卡住了,而没有重新合成原始图像。 由于我是一个完整的新手,因此非常感谢任何见解,干杯!

【问题讨论】:

    标签: sorting p5.js bubble-sort


    【解决方案1】:

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

    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];
    }
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"&gt;&lt;/script&gt;

    【讨论】:

    • 这真的帮助我理解了,谢谢@PaulWheeler。但是,我更多地考虑的是实际的反向冒泡排序,像素在相同的时间(或迭代)内排序。例如,我是否可以按时设置条件语句(例如,使用millis()),以便冒泡排序和反向排序代码在视觉上持续相同的时间?
    猜你喜欢
    • 2021-12-15
    • 2012-03-15
    • 2016-12-18
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    • 2011-01-06
    • 2020-05-24
    • 2014-02-13
    相关资源
    最近更新 更多