You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, applyGânicoInvert = "true", use16ColorPalette = "true") {
const canvas = document.createElement('canvas');
canvas.width = originalImg.width;
canvas.height = originalImg.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(originalImg, 0, 0);
const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imgData.data;
// Standard 16-color palette (VGA/EGA) heavily associated with retro 16-color filters
const palette16 = [
[0, 0, 0], [170, 0, 0], [0, 170, 0], [170, 85, 0],
[0, 0, 170], [170, 0, 170], [0, 170, 170], [170, 170, 170],
[85, 85, 85], [255, 85, 85], [85, 255, 85], [255, 255, 85],
[85, 85, 255], [255, 85, 255], [85, 255, 255], [255, 255, 255]
];
const doInvert = applyGânicoInvert === "true";
const doPalette = use16ColorPalette === "true";
for (let i = 0; i < data.length; i += 4) {
let r = data[i];
let g = data[i + 1];
let b = data[i + 2];
// 1. Apply "G Major" visual base effect (Inversion of colors)
if (doInvert) {
r = 255 - r;
g = 255 - g;
b = 255 - b;
}
// 2. Map exactly to 16 colors (16 Color Filter capability)
if (doPalette) {
let minDist = Infinity;
let closest = palette16[0];
for (let j = 0; j < palette16.length; j++) {
const pr = palette16[j][0];
const pg = palette16[j][1];
const pb = palette16[j][2];
// Fast Euclidean distance calculation in RGB space
const dist = (r - pr) * (r - pr) + (g - pg) * (g - pg) + (b - pb) * (b - pb);
if (dist < minDist) {
minDist = dist;
closest = palette16[j];
}
}
r = closest[0];
g = closest[1];
b = closest[2];
}
// Reassign processed values back to array (Alpha channel remains untouched)
data[i] = r;
data[i + 1] = g;
data[i + 2] = b;
}
ctx.putImageData(imgData, 0, 0);
return canvas;
}
Apply Changes