xxxxxxxxxx
124
let img;
let resultImg;
let redPix;
let greenPix;
let bluePix;
let redPixT;
let greenPixT;
let bluePixT;
let moveCount;
function preload() {
img = loadImage("https://picsum.photos/256");
}
function setup() {
createCanvas(512, 276);
image(img, 0, 0);
redPix = new Float32Array(65536);
greenPix = new Float32Array(65536);
bluePix = new Float32Array(65536);
redPixT = new Float32Array(65536);
greenPixT = new Float32Array(65536);
bluePixT = new Float32Array(65536);
redPixTC = new Float32Array(65536);
greenPixTC = new Float32Array(65536);
bluePixTC = new Float32Array(65536);
moveCount = 0;
for (let y = 0, idx = 0; y < 256; y++) {
for (let x = 0; x < 256; x++) {
let c = img.get(x, y);
redPix[idx] = red(c);
greenPix[idx] = green(c);
bluePix[idx] = blue(c);
idx++;
}
}
wht(redPix);
wht(greenPix);
wht(bluePix);
moveMaxMagnitude();
frameRate(5);
}
function draw() {
let whtScalingFactor = 1.0 / 65536;
for (let i = 0; i < 65536; i++) {
redPixTC[i] = redPixT[i] * whtScalingFactor;
greenPixTC[i] = greenPixT[i] * whtScalingFactor;
bluePixTC[i] = bluePixT[i] * whtScalingFactor;
}
//decompress
wht(redPixTC);
wht(greenPixTC);
wht(bluePixTC);
for (let y = 0, idx = 0; y < 256; y++) {
for (let x = 0; x < 256; x++) {
let r = constrain(redPixTC[idx], 0, 255);
let g = constrain(greenPixTC[idx], 0, 255);
let b = constrain(bluePixTC[idx], 0, 255);
idx++;
let c = color(r, g, b);
set(x + 256, y, c);
}
}
let cratio=(65536/moveCount);
let fx=cratio.toFixed(1);
updatePixels();
text("Approximate compression ratio 1 : "+fx,10,270);
if (moveCount < 65536) moveMaxMagnitude();
}
// Transfer max magnitude values to decompress arrays
// This should in practice be done with a sort algorithm and the
// found max magnitude values and positions stored for
// decompress.
function moveMaxMagnitude() {
let maxRed = 0;
let maxRedPos = 0;
let maxGreen = 0;
let maxGreenPos = 0;
let maxBlue = 0;
let maxBluePos = 0;
for (let i = 0; i < 65536; i++) {
if (abs(redPix[i]) > maxRed) {
maxRed = abs(redPix[i]);
maxRedPos = i;
}
if (abs(greenPix[i]) > maxGreen) {
maxGreen = abs(greenPix[i]);
maxGreenPos = i;
}
if (abs(bluePix[i]) > maxBlue) {
maxBlue = abs(bluePix[i]);
maxBluePos = i;
}
}
redPixT[maxRedPos] = redPix[maxRedPos]; //transfer
redPix[maxRedPos] = 0; // don't find again
greenPixT[maxGreenPos] = greenPix[maxGreenPos]; //transfer
greenPix[maxGreenPos] = 0; // don't find again
bluePixT[maxBluePos] = bluePix[maxBluePos]; //transfer
bluePix[maxBluePos] = 0; // don't find again
moveCount++;
}
// Fast Walsh Hadamard Transform
function wht(vec) {
const n = vec.length;
let hs = 1;
while (hs < n) {
let i = 0;
while (i < n) {
const j = i + hs;
while (i < j) {
var a = vec[i];
var b = vec[i + hs];
vec[i] = a + b;
vec[i + hs] = a - b;
i += 1;
}
i += hs;
}
hs += hs;
}
}