xxxxxxxxxx
179
let img;
let slider;
let label;
let posOld = 0;
let r = new Float32Array(65536);
let g = new Float32Array(65536);
let b = new Float32Array(65536);
let r1 = new Float32Array(65536);
let g1 = new Float32Array(65536);
let b1 = new Float32Array(65536);
let buffer = new Float32Array(65536);
let signFlips1 = new Float32Array(65536);
let signFlips2 = new Float32Array(65536);
// Load the image and create a p5.Image object.
function preload() {
img = loadImage("https://picsum.photos/256");
}
function setup() {
createCanvas(512, 256);
slider = createSlider(0, 65535);
label = createP();
image(img, 0, 0);
for (let i = 0; i < 65536; i++) {
signFlips1[i] = random(-1, 1) < 0 ? -1 : 1;
signFlips2[i] = random(-1, 1) < 0 ? -1 : 1;
}
getImg();
flip1(r);
whtN(r);
flip2(r);
whtN(r); // Random projection of red
flip1(g);
whtN(g); // Random projection of green
flip2(g);
whtN(g);
flip1(b);
whtN(b); // Random projection of blue
flip2(b);
whtN(b);
}
function draw() {
let pos = int(slider.value());
if (pos != posOld) {
posOld = pos;
for (let i = pos; i < 65536; i++) {
r1[i] = 0;
g1[i] = 0;
b1[i] = 0;
}
}
for (let i = 0; i < posOld; i++) {
r1[i] = r[i]; // copy sub-sample of Random Projection
g1[i] = g[i];
b1[i] = b[i];
}
whtN(r1);
flip2(r1); // invert RP of sub-sample
whtN(r1);
flip1(r1);
whtN(g1);
flip2(g1);
whtN(g1);
flip1(g1);
whtN(b1);
flip2(b1);
whtN(b1);
flip1(b1);
binomialFilter256(r1, buffer); // smooth image
binomialFilter256(g1, buffer);
binomialFilter256(b1, buffer);
putImg(256, 0);
updatePixels();
flip1(r1);
whtN(r1);
flip2(r1);
whtN(r1); // Random projection of red
flip1(g1);
whtN(g1); // Random projection of green
flip2(g1);
whtN(g1);
flip1(b1);
whtN(b1); // Random projection of blue
flip2(b1);
whtN(b1);
label.html("Percent:" + int((100 * pos) / 65536));
}
function flip1(vec) {
for (let i = 0; i < 65535; i++) {
vec[i] *= signFlips1[i];
}
}
function flip2(vec) {
for (let i = 0; i < 65535; i++) {
vec[i] *= signFlips2[i];
}
}
function getImg() {
for (let i = 0; i < 65536; i++) {
let x = i & 255;
let y = i >> 8;
let c = img.get(x, y);
r[i] = c[0];
g[i] = c[1];
b[i] = c[2];
}
}
function putImg(xoff, yoff) {
let c = [0, 0, 0, 255];
for (let i = 0; i < 65536; i++) {
let x = i & 255;
let y = i >> 8;
c[0] = r1[i];
c[1] = g1[i];
c[2] = b1[i];
set(x + xoff, y + yoff, c);
}
}
function whtN(vec) {
const n = vec.length;
const sc = 1.0 / sqrt(n);
for (let i = 0; i < n; i += 2) {
const a = vec[i];
const b = vec[i + 1];
vec[i] = (a + b) * sc;
vec[i + 1] = (a - b) * sc;
}
let hs = 2;
while (hs < n) {
let i = 0;
while (i < n) {
const j = i + hs;
while (i < j) {
const a = vec[i];
const b = vec[i + hs];
vec[i] = a + b;
vec[i + hs] = a - b;
i += 1;
}
i += hs;
}
hs += hs;
}
}
function binomialFilter256(img, buffer) {
for (let y = 0; y < 256; y++) {
let idx = y * 256;
let a;
let b = img[idx];
let c = b;
for (let x = 0; x < 255; x++) {
a = b;
b = c;
c = img[idx + x + 1];
buffer[idx + x] = 0.25 * a + 0.5 * b + 0.25 * c;
}
buffer[idx + 255] = 0.25 * b + 0.75 * c;
}
for (let x = 0; x < 256; x++) {
let a;
let b = img[x];
let c = b;
for (let y = 0; y < 255; y++) {
let idx = y * 256;
a = b;
b = c;
c = buffer[idx + x + 256];
img[idx + x] = 0.25 * a + 0.5 * b + 0.25 * c;
}
img[255 * 256 + x] = 0.25 * b + 0.75 * c;
}
}