98 lines
2.2 KiB
JavaScript
98 lines
2.2 KiB
JavaScript
![]() |
const img = document.querySelector('img');
|
||
|
|
||
|
function matmul(m,v) {
|
||
|
return m.map(r => r[0]*v[0] + r[1]*v[1] + r[2]*v[2]);
|
||
|
}
|
||
|
|
||
|
/* From https://www.inf.ufrgs.br/~oliveira/pubs_files/CVD_Simulation/CVD_Simulation.html#Tutorial
|
||
|
*/
|
||
|
const protan = [
|
||
|
[0.152286 , 1.052583 , -0.204868],
|
||
|
[0.114503 , 0.786281 , 0.099216],
|
||
|
[-0.003882 , -0.048116 , 1.051998],
|
||
|
];
|
||
|
|
||
|
const deuteran = [
|
||
|
[0.367322 , 0.860646 , -0.227968],
|
||
|
[0.280085 , 0.672501 , 0.047413],
|
||
|
[-0.011820 , 0.042940 , 0.968881],
|
||
|
]
|
||
|
|
||
|
const tritan = [
|
||
|
[1.255528 , -0.076749 , -0.178779],
|
||
|
[-0.078411 , 0.930809 , 0.147602],
|
||
|
[0.004733 , 0.691367 , 0.303900],
|
||
|
];
|
||
|
|
||
|
async function filter(canvas, matrix) {
|
||
|
const {naturalWidth, naturalHeight} = img;
|
||
|
const width = Math.min(2*img.width, naturalWidth);
|
||
|
const height = naturalHeight/naturalWidth * width;
|
||
|
canvas.width = width;
|
||
|
canvas.height = height;
|
||
|
const ctx = canvas.getContext('2d');
|
||
|
ctx.drawImage(img,0,0,width,height);
|
||
|
const {data} = ctx.getImageData(0,0,width,height);
|
||
|
for(let i=0;i<data.length;i+=4) {
|
||
|
const v = data.slice(i,i+3);
|
||
|
const [r,g,b] = matmul(matrix, v);
|
||
|
data[i] = r;
|
||
|
data[i+1] = g;
|
||
|
data[i+2] = b;
|
||
|
}
|
||
|
const nimagedata = new ImageData(data,width,height);
|
||
|
|
||
|
ctx.putImageData(nimagedata,0,0);
|
||
|
}
|
||
|
|
||
|
async function go() {
|
||
|
console.log('loaded');
|
||
|
|
||
|
const sims = {
|
||
|
protan, deuteran, tritan
|
||
|
}
|
||
|
|
||
|
console.log(img.width, img.height);
|
||
|
|
||
|
Object.entries(sims).forEach(async ([k,m]) => {
|
||
|
const canvas = document.getElementById(k).querySelector('canvas');
|
||
|
const blob = await filter(canvas, m);
|
||
|
sim_img.src = URL.createObjectURL(blob);
|
||
|
})
|
||
|
}
|
||
|
|
||
|
if(img.complete) {
|
||
|
go();
|
||
|
} else {
|
||
|
img.addEventListener('load', go, {once:true});
|
||
|
}
|
||
|
|
||
|
document.body.addEventListener('dragover', e => {
|
||
|
e.preventDefault();
|
||
|
e.stopPropagation();
|
||
|
})
|
||
|
|
||
|
function load_file(file) {
|
||
|
img.src = URL.createObjectURL(file);
|
||
|
img.addEventListener('load', go, {once:true});
|
||
|
}
|
||
|
|
||
|
document.body.addEventListener('drop', e => {
|
||
|
e.preventDefault();
|
||
|
e.stopPropagation();
|
||
|
|
||
|
const [file] = e.dataTransfer.files;
|
||
|
if(!file) {
|
||
|
return;
|
||
|
}
|
||
|
load_file(file);
|
||
|
})
|
||
|
|
||
|
document.getElementById('file').addEventListener('change', ({target}) => {
|
||
|
const [file] = target.files;
|
||
|
console.log(file);
|
||
|
if(!file) {
|
||
|
return;
|
||
|
}
|
||
|
load_file(file);
|
||
|
})
|