CoolFace
Apppublic

HarshvardhanCn01/Voice-Assistant

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
conversions.js840 linesDownload Raw Back to color-convert
1/* MIT license */2/* eslint-disable no-mixed-operators */3const cssKeywords = require('color-name');4 5// NOTE: conversions should only return primitive values (i.e. arrays, or6//       values that give correct `typeof` results).7//       do not use box values types (i.e. Number(), String(), etc.)8 9const reverseKeywords = {};10for (const key of Object.keys(cssKeywords)) {11	reverseKeywords[cssKeywords[key]] = key;12}13 14const convert = {15	rgb: {channels: 3, labels: 'rgb'},16	hsl: {channels: 3, labels: 'hsl'},17	hsv: {channels: 3, labels: 'hsv'},18	hwb: {channels: 3, labels: 'hwb'},19	cmyk: {channels: 4, labels: 'cmyk'},20	xyz: {channels: 3, labels: 'xyz'},21	lab: {channels: 3, labels: 'lab'},22	lch: {channels: 3, labels: 'lch'},23	hex: {channels: 1, labels: ['hex']},24	keyword: {channels: 1, labels: ['keyword']},25	ansi16: {channels: 1, labels: ['ansi16']},26	ansi256: {channels: 1, labels: ['ansi256']},27	hcg: {channels: 3, labels: ['h', 'c', 'g']},28	apple: {channels: 3, labels: ['r16', 'g16', 'b16']},29	gray: {channels: 1, labels: ['gray']}30};31 32module.exports = convert;33 34// Hide .channels and .labels properties35for (const model of Object.keys(convert)) {36	if (!('channels' in convert[model])) {37		throw new Error('missing channels property: ' + model);38	}39 40	if (!('labels' in convert[model])) {41		throw new Error('missing channel labels property: ' + model);42	}43 44	if (convert[model].labels.length !== convert[model].channels) {45		throw new Error('channel and label counts mismatch: ' + model);46	}47 48	const {channels, labels} = convert[model];49	delete convert[model].channels;50	delete convert[model].labels;51	Object.defineProperty(convert[model], 'channels', {value: channels});52	Object.defineProperty(convert[model], 'labels', {value: labels});53}54 55convert.rgb.hsl = function (rgb) {56	const r = rgb[0] / 255;57	const g = rgb[1] / 255;58	const b = rgb[2] / 255;59	const min = Math.min(r, g, b);60	const max = Math.max(r, g, b);61	const delta = max - min;62	let h;63	let s;64 65	if (max === min) {66		h = 0;67	} else if (r === max) {68		h = (g - b) / delta;69	} else if (g === max) {70		h = 2 + (b - r) / delta;71	} else if (b === max) {72		h = 4 + (r - g) / delta;73	}74 75	h = Math.min(h * 60, 360);76 77	if (h < 0) {78		h += 360;79	}80 81	const l = (min + max) / 2;82 83	if (max === min) {84		s = 0;85	} else if (l <= 0.5) {86		s = delta / (max + min);87	} else {88		s = delta / (2 - max - min);89	}90 91	return [h, s * 100, l * 100];92};93 94convert.rgb.hsv = function (rgb) {95	let rdif;96	let gdif;97	let bdif;98	let h;99	let s;100 101	const r = rgb[0] / 255;102	const g = rgb[1] / 255;103	const b = rgb[2] / 255;104	const v = Math.max(r, g, b);105	const diff = v - Math.min(r, g, b);106	const diffc = function (c) {107		return (v - c) / 6 / diff + 1 / 2;108	};109 110	if (diff === 0) {111		h = 0;112		s = 0;113	} else {114		s = diff / v;115		rdif = diffc(r);116		gdif = diffc(g);117		bdif = diffc(b);118 119		if (r === v) {120			h = bdif - gdif;121		} else if (g === v) {122			h = (1 / 3) + rdif - bdif;123		} else if (b === v) {124			h = (2 / 3) + gdif - rdif;125		}126 127		if (h < 0) {128			h += 1;129		} else if (h > 1) {130			h -= 1;131		}132	}133 134	return [135		h * 360,136		s * 100,137		v * 100138	];139};140 141convert.rgb.hwb = function (rgb) {142	const r = rgb[0];143	const g = rgb[1];144	let b = rgb[2];145	const h = convert.rgb.hsl(rgb)[0];146	const w = 1 / 255 * Math.min(r, Math.min(g, b));147 148	b = 1 - 1 / 255 * Math.max(r, Math.max(g, b));149 150	return [h, w * 100, b * 100];151};152 153convert.rgb.cmyk = function (rgb) {154	const r = rgb[0] / 255;155	const g = rgb[1] / 255;156	const b = rgb[2] / 255;157 158	const k = Math.min(1 - r, 1 - g, 1 - b);159	const c = (1 - r - k) / (1 - k) || 0;160	const m = (1 - g - k) / (1 - k) || 0;161	const y = (1 - b - k) / (1 - k) || 0;162 163	return [c * 100, m * 100, y * 100, k * 100];164};165 166function comparativeDistance(x, y) {167	/*168		See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance169	*/170	return (171		((x[0] - y[0]) ** 2) +172		((x[1] - y[1]) ** 2) +173		((x[2] - y[2]) ** 2)174	);175}176 177convert.rgb.keyword = function (rgb) {178	const reversed = reverseKeywords[rgb];179	if (reversed) {180		return reversed;181	}182 183	let currentClosestDistance = Infinity;184	let currentClosestKeyword;185 186	for (const keyword of Object.keys(cssKeywords)) {187		const value = cssKeywords[keyword];188 189		// Compute comparative distance190		const distance = comparativeDistance(rgb, value);191 192		// Check if its less, if so set as closest193		if (distance < currentClosestDistance) {194			currentClosestDistance = distance;195			currentClosestKeyword = keyword;196		}197	}198 199	return currentClosestKeyword;200};201 202convert.keyword.rgb = function (keyword) {203	return cssKeywords[keyword];204};205 206convert.rgb.xyz = function (rgb) {207	let r = rgb[0] / 255;208	let g = rgb[1] / 255;209	let b = rgb[2] / 255;210 211	// Assume sRGB212	r = r > 0.04045 ? (((r + 0.055) / 1.055) ** 2.4) : (r / 12.92);213	g = g > 0.04045 ? (((g + 0.055) / 1.055) ** 2.4) : (g / 12.92);214	b = b > 0.04045 ? (((b + 0.055) / 1.055) ** 2.4) : (b / 12.92);215 216	const x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);217	const y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);218	const z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);219 220	return [x * 100, y * 100, z * 100];221};222 223convert.rgb.lab = function (rgb) {224	const xyz = convert.rgb.xyz(rgb);225	let x = xyz[0];226	let y = xyz[1];227	let z = xyz[2];228 229	x /= 95.047;230	y /= 100;231	z /= 108.883;232 233	x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116);234	y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116);235	z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116);236 237	const l = (116 * y) - 16;238	const a = 500 * (x - y);239	const b = 200 * (y - z);240 241	return [l, a, b];242};243 244convert.hsl.rgb = function (hsl) {245	const h = hsl[0] / 360;246	const s = hsl[1] / 100;247	const l = hsl[2] / 100;248	let t2;249	let t3;250	let val;251 252	if (s === 0) {253		val = l * 255;254		return [val, val, val];255	}256 257	if (l < 0.5) {258		t2 = l * (1 + s);259	} else {260		t2 = l + s - l * s;261	}262 263	const t1 = 2 * l - t2;264 265	const rgb = [0, 0, 0];266	for (let i = 0; i < 3; i++) {267		t3 = h + 1 / 3 * -(i - 1);268		if (t3 < 0) {269			t3++;270		}271 272		if (t3 > 1) {273			t3--;274		}275 276		if (6 * t3 < 1) {277			val = t1 + (t2 - t1) * 6 * t3;278		} else if (2 * t3 < 1) {279			val = t2;280		} else if (3 * t3 < 2) {281			val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;282		} else {283			val = t1;284		}285 286		rgb[i] = val * 255;287	}288 289	return rgb;290};291 292convert.hsl.hsv = function (hsl) {293	const h = hsl[0];294	let s = hsl[1] / 100;295	let l = hsl[2] / 100;296	let smin = s;297	const lmin = Math.max(l, 0.01);298 299	l *= 2;300	s *= (l <= 1) ? l : 2 - l;301	smin *= lmin <= 1 ? lmin : 2 - lmin;302	const v = (l + s) / 2;303	const sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);304 305	return [h, sv * 100, v * 100];306};307 308convert.hsv.rgb = function (hsv) {309	const h = hsv[0] / 60;310	const s = hsv[1] / 100;311	let v = hsv[2] / 100;312	const hi = Math.floor(h) % 6;313 314	const f = h - Math.floor(h);315	const p = 255 * v * (1 - s);316	const q = 255 * v * (1 - (s * f));317	const t = 255 * v * (1 - (s * (1 - f)));318	v *= 255;319 320	switch (hi) {321		case 0:322			return [v, t, p];323		case 1:324			return [q, v, p];325		case 2:326			return [p, v, t];327		case 3:328			return [p, q, v];329		case 4:330			return [t, p, v];331		case 5:332			return [v, p, q];333	}334};335 336convert.hsv.hsl = function (hsv) {337	const h = hsv[0];338	const s = hsv[1] / 100;339	const v = hsv[2] / 100;340	const vmin = Math.max(v, 0.01);341	let sl;342	let l;343 344	l = (2 - s) * v;345	const lmin = (2 - s) * vmin;346	sl = s * vmin;347	sl /= (lmin <= 1) ? lmin : 2 - lmin;348	sl = sl || 0;349	l /= 2;350 351	return [h, sl * 100, l * 100];352};353 354// http://dev.w3.org/csswg/css-color/#hwb-to-rgb355convert.hwb.rgb = function (hwb) {356	const h = hwb[0] / 360;357	let wh = hwb[1] / 100;358	let bl = hwb[2] / 100;359	const ratio = wh + bl;360	let f;361 362	// Wh + bl cant be > 1363	if (ratio > 1) {364		wh /= ratio;365		bl /= ratio;366	}367 368	const i = Math.floor(6 * h);369	const v = 1 - bl;370	f = 6 * h - i;371 372	if ((i & 0x01) !== 0) {373		f = 1 - f;374	}375 376	const n = wh + f * (v - wh); // Linear interpolation377 378	let r;379	let g;380	let b;381	/* eslint-disable max-statements-per-line,no-multi-spaces */382	switch (i) {383		default:384		case 6:385		case 0: r = v;  g = n;  b = wh; break;386		case 1: r = n;  g = v;  b = wh; break;387		case 2: r = wh; g = v;  b = n; break;388		case 3: r = wh; g = n;  b = v; break;389		case 4: r = n;  g = wh; b = v; break;390		case 5: r = v;  g = wh; b = n; break;391	}392	/* eslint-enable max-statements-per-line,no-multi-spaces */393 394	return [r * 255, g * 255, b * 255];395};396 397convert.cmyk.rgb = function (cmyk) {398	const c = cmyk[0] / 100;399	const m = cmyk[1] / 100;400	const y = cmyk[2] / 100;401	const k = cmyk[3] / 100;402 403	const r = 1 - Math.min(1, c * (1 - k) + k);404	const g = 1 - Math.min(1, m * (1 - k) + k);405	const b = 1 - Math.min(1, y * (1 - k) + k);406 407	return [r * 255, g * 255, b * 255];408};409 410convert.xyz.rgb = function (xyz) {411	const x = xyz[0] / 100;412	const y = xyz[1] / 100;413	const z = xyz[2] / 100;414	let r;415	let g;416	let b;417 418	r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);419	g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);420	b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);421 422	// Assume sRGB423	r = r > 0.0031308424		? ((1.055 * (r ** (1.0 / 2.4))) - 0.055)425		: r * 12.92;426 427	g = g > 0.0031308428		? ((1.055 * (g ** (1.0 / 2.4))) - 0.055)429		: g * 12.92;430 431	b = b > 0.0031308432		? ((1.055 * (b ** (1.0 / 2.4))) - 0.055)433		: b * 12.92;434 435	r = Math.min(Math.max(0, r), 1);436	g = Math.min(Math.max(0, g), 1);437	b = Math.min(Math.max(0, b), 1);438 439	return [r * 255, g * 255, b * 255];440};441 442convert.xyz.lab = function (xyz) {443	let x = xyz[0];444	let y = xyz[1];445	let z = xyz[2];446 447	x /= 95.047;448	y /= 100;449	z /= 108.883;450 451	x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116);452	y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116);453	z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116);454 455	const l = (116 * y) - 16;456	const a = 500 * (x - y);457	const b = 200 * (y - z);458 459	return [l, a, b];460};461 462convert.lab.xyz = function (lab) {463	const l = lab[0];464	const a = lab[1];465	const b = lab[2];466	let x;467	let y;468	let z;469 470	y = (l + 16) / 116;471	x = a / 500 + y;472	z = y - b / 200;473 474	const y2 = y ** 3;475	const x2 = x ** 3;476	const z2 = z ** 3;477	y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787;478	x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787;479	z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787;480 481	x *= 95.047;482	y *= 100;483	z *= 108.883;484 485	return [x, y, z];486};487 488convert.lab.lch = function (lab) {489	const l = lab[0];490	const a = lab[1];491	const b = lab[2];492	let h;493 494	const hr = Math.atan2(b, a);495	h = hr * 360 / 2 / Math.PI;496 497	if (h < 0) {498		h += 360;499	}500 501	const c = Math.sqrt(a * a + b * b);502 503	return [l, c, h];504};505 506convert.lch.lab = function (lch) {507	const l = lch[0];508	const c = lch[1];509	const h = lch[2];510 511	const hr = h / 360 * 2 * Math.PI;512	const a = c * Math.cos(hr);513	const b = c * Math.sin(hr);514 515	return [l, a, b];516};517 518convert.rgb.ansi16 = function (args, saturation = null) {519	const [r, g, b] = args;520	let value = saturation === null ? convert.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization521 522	value = Math.round(value / 50);523 524	if (value === 0) {525		return 30;526	}527 528	let ansi = 30529		+ ((Math.round(b / 255) << 2)530		| (Math.round(g / 255) << 1)531		| Math.round(r / 255));532 533	if (value === 2) {534		ansi += 60;535	}536 537	return ansi;538};539 540convert.hsv.ansi16 = function (args) {541	// Optimization here; we already know the value and don't need to get542	// it converted for us.543	return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);544};545 546convert.rgb.ansi256 = function (args) {547	const r = args[0];548	const g = args[1];549	const b = args[2];550 551	// We use the extended greyscale palette here, with the exception of552	// black and white. normal palette only has 4 greyscale shades.553	if (r === g && g === b) {554		if (r < 8) {555			return 16;556		}557 558		if (r > 248) {559			return 231;560		}561 562		return Math.round(((r - 8) / 247) * 24) + 232;563	}564 565	const ansi = 16566		+ (36 * Math.round(r / 255 * 5))567		+ (6 * Math.round(g / 255 * 5))568		+ Math.round(b / 255 * 5);569 570	return ansi;571};572 573convert.ansi16.rgb = function (args) {574	let color = args % 10;575 576	// Handle greyscale577	if (color === 0 || color === 7) {578		if (args > 50) {579			color += 3.5;580		}581 582		color = color / 10.5 * 255;583 584		return [color, color, color];585	}586 587	const mult = (~~(args > 50) + 1) * 0.5;588	const r = ((color & 1) * mult) * 255;589	const g = (((color >> 1) & 1) * mult) * 255;590	const b = (((color >> 2) & 1) * mult) * 255;591 592	return [r, g, b];593};594 595convert.ansi256.rgb = function (args) {596	// Handle greyscale597	if (args >= 232) {598		const c = (args - 232) * 10 + 8;599		return [c, c, c];600	}601 602	args -= 16;603 604	let rem;605	const r = Math.floor(args / 36) / 5 * 255;606	const g = Math.floor((rem = args % 36) / 6) / 5 * 255;607	const b = (rem % 6) / 5 * 255;608 609	return [r, g, b];610};611 612convert.rgb.hex = function (args) {613	const integer = ((Math.round(args[0]) & 0xFF) << 16)614		+ ((Math.round(args[1]) & 0xFF) << 8)615		+ (Math.round(args[2]) & 0xFF);616 617	const string = integer.toString(16).toUpperCase();618	return '000000'.substring(string.length) + string;619};620 621convert.hex.rgb = function (args) {622	const match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);623	if (!match) {624		return [0, 0, 0];625	}626 627	let colorString = match[0];628 629	if (match[0].length === 3) {630		colorString = colorString.split('').map(char => {631			return char + char;632		}).join('');633	}634 635	const integer = parseInt(colorString, 16);636	const r = (integer >> 16) & 0xFF;637	const g = (integer >> 8) & 0xFF;638	const b = integer & 0xFF;639 640	return [r, g, b];641};642 643convert.rgb.hcg = function (rgb) {644	const r = rgb[0] / 255;645	const g = rgb[1] / 255;646	const b = rgb[2] / 255;647	const max = Math.max(Math.max(r, g), b);648	const min = Math.min(Math.min(r, g), b);649	const chroma = (max - min);650	let grayscale;651	let hue;652 653	if (chroma < 1) {654		grayscale = min / (1 - chroma);655	} else {656		grayscale = 0;657	}658 659	if (chroma <= 0) {660		hue = 0;661	} else662	if (max === r) {663		hue = ((g - b) / chroma) % 6;664	} else665	if (max === g) {666		hue = 2 + (b - r) / chroma;667	} else {668		hue = 4 + (r - g) / chroma;669	}670 671	hue /= 6;672	hue %= 1;673 674	return [hue * 360, chroma * 100, grayscale * 100];675};676 677convert.hsl.hcg = function (hsl) {678	const s = hsl[1] / 100;679	const l = hsl[2] / 100;680 681	const c = l < 0.5 ? (2.0 * s * l) : (2.0 * s * (1.0 - l));682 683	let f = 0;684	if (c < 1.0) {685		f = (l - 0.5 * c) / (1.0 - c);686	}687 688	return [hsl[0], c * 100, f * 100];689};690 691convert.hsv.hcg = function (hsv) {692	const s = hsv[1] / 100;693	const v = hsv[2] / 100;694 695	const c = s * v;696	let f = 0;697 698	if (c < 1.0) {699		f = (v - c) / (1 - c);700	}701 702	return [hsv[0], c * 100, f * 100];703};704 705convert.hcg.rgb = function (hcg) {706	const h = hcg[0] / 360;707	const c = hcg[1] / 100;708	const g = hcg[2] / 100;709 710	if (c === 0.0) {711		return [g * 255, g * 255, g * 255];712	}713 714	const pure = [0, 0, 0];715	const hi = (h % 1) * 6;716	const v = hi % 1;717	const w = 1 - v;718	let mg = 0;719 720	/* eslint-disable max-statements-per-line */721	switch (Math.floor(hi)) {722		case 0:723			pure[0] = 1; pure[1] = v; pure[2] = 0; break;724		case 1:725			pure[0] = w; pure[1] = 1; pure[2] = 0; break;726		case 2:727			pure[0] = 0; pure[1] = 1; pure[2] = v; break;728		case 3:729			pure[0] = 0; pure[1] = w; pure[2] = 1; break;730		case 4:731			pure[0] = v; pure[1] = 0; pure[2] = 1; break;732		default:733			pure[0] = 1; pure[1] = 0; pure[2] = w;734	}735	/* eslint-enable max-statements-per-line */736 737	mg = (1.0 - c) * g;738 739	return [740		(c * pure[0] + mg) * 255,741		(c * pure[1] + mg) * 255,742		(c * pure[2] + mg) * 255743	];744};745 746convert.hcg.hsv = function (hcg) {747	const c = hcg[1] / 100;748	const g = hcg[2] / 100;749 750	const v = c + g * (1.0 - c);751	let f = 0;752 753	if (v > 0.0) {754		f = c / v;755	}756 757	return [hcg[0], f * 100, v * 100];758};759 760convert.hcg.hsl = function (hcg) {761	const c = hcg[1] / 100;762	const g = hcg[2] / 100;763 764	const l = g * (1.0 - c) + 0.5 * c;765	let s = 0;766 767	if (l > 0.0 && l < 0.5) {768		s = c / (2 * l);769	} else770	if (l >= 0.5 && l < 1.0) {771		s = c / (2 * (1 - l));772	}773 774	return [hcg[0], s * 100, l * 100];775};776 777convert.hcg.hwb = function (hcg) {778	const c = hcg[1] / 100;779	const g = hcg[2] / 100;780	const v = c + g * (1.0 - c);781	return [hcg[0], (v - c) * 100, (1 - v) * 100];782};783 784convert.hwb.hcg = function (hwb) {785	const w = hwb[1] / 100;786	const b = hwb[2] / 100;787	const v = 1 - b;788	const c = v - w;789	let g = 0;790 791	if (c < 1) {792		g = (v - c) / (1 - c);793	}794 795	return [hwb[0], c * 100, g * 100];796};797 798convert.apple.rgb = function (apple) {799	return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255];800};801 802convert.rgb.apple = function (rgb) {803	return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535];804};805 806convert.gray.rgb = function (args) {807	return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];808};809 810convert.gray.hsl = function (args) {811	return [0, 0, args[0]];812};813 814convert.gray.hsv = convert.gray.hsl;815 816convert.gray.hwb = function (gray) {817	return [0, 100, gray[0]];818};819 820convert.gray.cmyk = function (gray) {821	return [0, 0, 0, gray[0]];822};823 824convert.gray.lab = function (gray) {825	return [gray[0], 0, 0];826};827 828convert.gray.hex = function (gray) {829	const val = Math.round(gray[0] / 100 * 255) & 0xFF;830	const integer = (val << 16) + (val << 8) + val;831 832	const string = integer.toString(16).toUpperCase();833	return '000000'.substring(string.length) + string;834};835 836convert.rgb.gray = function (rgb) {837	const val = (rgb[0] + rgb[1] + rgb[2]) / 3;838	return [val / 255 * 100];839};840