Skip to content

Instantly share code, notes, and snippets.

@innermond
Created March 29, 2021 10:45
Show Gist options
  • Save innermond/4ee8c5329993e02b1718142380ec76e8 to your computer and use it in GitHub Desktop.
Save innermond/4ee8c5329993e02b1718142380ec76e8 to your computer and use it in GitHub Desktop.
calculate with aproximation CMYK coverage color for anything can be src of a html img tag
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<input type="file" accept="image/*" name="image" id="file" style="display: none;" onchange="loadFile(event)" >
<p><label for="file" style="cursor: pointer;">Upload Image</label></p>
<img id="output" width="200" />
<canvas id="myCanvas" width="220" height="277" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var loadFile = function(event) {
var img = document.getElementById('output');
img.addEventListener('load', function(){
var c = document.getElementById("myCanvas");
c.width = img.width;
c.height =img.height;
var ctx = c.getContext("2d");
ctx.scale(img.width/img.naturalWidth, img.height/img.naturalHeight);
ctx.drawImage(img, 0, 0);
var imgData = ctx.getImageData(0, 0, c.width, c.height);
// offload to a worker
var cent = colors_percentage(imgData.data)
console.log(cent)
});
img.src = URL.createObjectURL(event.target.files[0]);
};
function cycle_colors(d, bkg) {
var cent = [0,0,0,0];
var val;
var i;
var a;
var l=0;
var kpart;
for (i = 0; i < d.length; i += 4) {
a = d[i+3];
a = clamp(a, 0, 255, 0, 1);
val = rgba_bkg(d[i], d[i+1], d[i+2], a, bkg, bkg, bkg);
// cmyk is suspect
val = rgb_cmyk(val[0], val[1], val[2]);
cent[0] += val[0];
cent[1] += val[1];
cent[2] += val[2];
cent[3] += val[3];
l++;
}
return cent.map(x=>x/l);
}
function colors_percentage(src) {
var cent = cycle_colors(src, 255);
var k = 1;// + cent[3]/1.74;// blind empiric number to catch few ghostscript estimations that I have made
cent = cent.reduce((acc, x)=>acc+=x, 0)*100;
cent = round(cent*k, 2);
console.log(cent);
}
function round(value, decimals) {
return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}
function clamp (me, in_min, in_max, out_min, out_max) {
return (me - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
function rgb_cmyk (r, g, b){
var computedC = 0;
var computedM = 0;
var computedY = 0;
var computedK = 0;
if (r==0 && g==0 && b==0) {
return [0,0,0,1];
}
computedC = 1 - (r/255);
computedM = 1 - (g/255);
computedY = 1 - (b/255);
var minCMY = Math.min(computedC,
Math.min(computedM,computedY));
// push cmy to black
computedC = (computedC - minCMY) / (1 - minCMY) ;
computedM = (computedM - minCMY) / (1 - minCMY) ;
computedY = (computedY - minCMY) / (1 - minCMY) ;
computedK = minCMY;
// push black to cmy - convert cmyk to cmy
var blackC = ( computedC * ( 1 - computedK ) + computedK );
var blackM = ( computedM * ( 1 - computedK ) + computedK );
var blackY = ( computedY * ( 1 - computedK ) + computedK );
var pureK = computedK - ((blackC - computedC) + (blackM - computedM) + (blackY - computedY))/3;
pureK = Math.max(0, pureK);
return [blackC,blackM,blackY,pureK];
}
function rgba_bkg(r, g, b, a, r2,g2,b2){
var r3 = Math.round(((1 - a) * r2) + (a * r))
var g3 = Math.round(((1 - a) * g2) + (a * g))
var b3 = Math.round(((1 - a) * b2) + (a * b))
return [r3,g3,b3];
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment