chromaticity-color-utilities
Advanced tools
Comparing version 0.1.3-alpha to 0.1.5-alpha
@@ -14,2 +14,3 @@ export interface newColorArgs { | ||
cUpper?: number; | ||
gamma?: number; | ||
} | ||
@@ -27,3 +28,21 @@ export interface modifyArgs { | ||
to(type: string, args?: newColorArgs): colorType | any; | ||
setArgs(args?: newColorArgs): newColorArgs; | ||
modify(modification: string, args?: modifyArgs): colorType; | ||
scheme(type: string, args?: schemeArgs): colorType[]; | ||
css(): string; | ||
protected torgb(args: newColorArgs): rgb; | ||
protected torec709(args: newColorArgs): rec709rgb; | ||
protected torec2020(args: newColorArgs): rec2020rgb; | ||
protected tohex(args: newColorArgs): hex; | ||
protected tohsv(args: newColorArgs): hsv; | ||
protected tohsl(args: newColorArgs): hsl; | ||
protected tohsi(args: newColorArgs): hsi; | ||
protected tocmyk(args: newColorArgs): cmyk; | ||
protected toyiq(args: newColorArgs): yiq; | ||
protected toxyz(args: newColorArgs): xyz; | ||
protected toxyy(args: newColorArgs): xyy; | ||
protected tolab(args: newColorArgs): lab; | ||
protected toluv(args: newColorArgs): luv; | ||
protected toypbpr(args: newColorArgs): ypbpr; | ||
protected toycbcr(args: newColorArgs): ycbcr; | ||
protected setArgs(args?: newColorArgs): newColorArgs; | ||
/** | ||
@@ -38,6 +57,3 @@ * Range check to make sure numeric value is within lower and upper limits | ||
*/ | ||
valueRangeCheck(value: number, lowerLimit: number | boolean, upperLimit: number | boolean, msg?: string): void; | ||
modify(modification: string, args?: modifyArgs): colorType; | ||
scheme(type: string, args?: schemeArgs): colorType[]; | ||
css(): string; | ||
protected valueRangeCheck(value: number, lowerLimit: number | boolean, upperLimit: number | boolean, msg?: string): void; | ||
} | ||
@@ -47,3 +63,4 @@ export declare class hex extends colorType { | ||
constructor(hex: string); | ||
to(type: string, args?: newColorArgs): colorType; | ||
protected torgb(args: newColorArgs): rgb; | ||
protected tohex(args: newColorArgs): hex; | ||
} | ||
@@ -66,3 +83,3 @@ export declare class rgbNormalized extends colorType { | ||
constructor(r: number, g: number, b: number, a?: number, bitDepth?: number); | ||
to(type: string, args?: newColorArgs): colorType; | ||
protected torgb(args: newColorArgs): rgb; | ||
} | ||
@@ -77,3 +94,4 @@ export declare class rec709rgb extends colorType { | ||
constructor(r: number, g: number, b: number, a?: number, bitDepth?: number); | ||
to(type: string, args?: newColorArgs): colorType; | ||
protected torgb(args: newColorArgs): rgb; | ||
protected torec709(args: newColorArgs): rec709rgb; | ||
} | ||
@@ -88,3 +106,4 @@ export declare class rec2020rgb extends colorType { | ||
constructor(r: number, g: number, b: number, a?: number, bitDepth?: number); | ||
to(type: string, args?: newColorArgs): colorType; | ||
protected torgb(args: newColorArgs): rgb; | ||
protected torec2020(args: newColorArgs): rec2020rgb; | ||
} | ||
@@ -97,3 +116,6 @@ export declare class hsv extends colorType { | ||
constructor(h: number, s: number, v: number, a?: number); | ||
to(type: string, args?: newColorArgs): colorType; | ||
protected torgb(args: newColorArgs): rgb; | ||
protected tohsv(args: newColorArgs): hsv; | ||
protected tohsl(args: newColorArgs): hsl; | ||
protected tohsi(args: newColorArgs): hsi; | ||
} | ||
@@ -106,3 +128,6 @@ export declare class hsl extends colorType { | ||
constructor(h: number, s: number, l: number, a?: number); | ||
to(type: string, args?: newColorArgs): colorType; | ||
protected torgb(args: newColorArgs): rgb; | ||
protected tohsv(args: newColorArgs): hsv; | ||
protected tohsl(args: newColorArgs): hsl; | ||
protected tohsi(args: newColorArgs): hsi; | ||
} | ||
@@ -115,3 +140,6 @@ export declare class hsi extends colorType { | ||
constructor(h: number, s: number, i: number, a?: number); | ||
to(type: string, args?: newColorArgs): colorType; | ||
protected torgb(args: newColorArgs): rgb; | ||
protected tohsv(args: newColorArgs): hsv; | ||
protected tohsl(args: newColorArgs): hsl; | ||
protected tohsi(args: newColorArgs): hsi; | ||
} | ||
@@ -124,3 +152,4 @@ export declare class cmyk extends colorType { | ||
constructor(c: number, m: number, y: number, k: number); | ||
to(type: string, args?: newColorArgs): colorType; | ||
protected torgb(args: newColorArgs): rgb; | ||
protected tocmyk(args: newColorArgs): cmyk; | ||
} | ||
@@ -141,3 +170,4 @@ export declare class yiq extends colorType { | ||
constructor(y: number, i: number, q: number, normalized?: boolean); | ||
to(type: string, args?: newColorArgs): colorType; | ||
protected torgb(args: newColorArgs): rgb; | ||
protected toyiq(args: newColorArgs): yiq; | ||
} | ||
@@ -151,3 +181,4 @@ export declare class xyz extends colorType { | ||
constructor(x: number, y: number, z: number, colorSpace?: string, referenceWhite?: string); | ||
to(type: string, args?: newColorArgs): colorType; | ||
protected torgb(args: newColorArgs): rgb; | ||
protected toxyz(args: newColorArgs): xyz; | ||
} | ||
@@ -161,3 +192,5 @@ export declare class xyy extends colorType { | ||
constructor(x: number, y: number, yy: number, colorSpace?: string, referenceWhite?: string); | ||
to(type: string, args?: newColorArgs): colorType; | ||
protected torgb(args: newColorArgs): rgb; | ||
protected toxyz(args: newColorArgs): xyz; | ||
protected toxyy(args: newColorArgs): xyy; | ||
} | ||
@@ -179,3 +212,5 @@ export declare class lab extends colorType { | ||
constructor(l: number, a: number, b: number, colorSpace?: string, referenceWhite?: string); | ||
to(type: string, args?: newColorArgs): colorType; | ||
protected torgb(args: newColorArgs): rgb; | ||
protected toxyz(args: newColorArgs): xyz; | ||
protected tolab(args: newColorArgs): lab; | ||
} | ||
@@ -197,3 +232,5 @@ export declare class luv extends colorType { | ||
constructor(l: number, u: number, v: number, colorSpace?: string, referenceWhite?: string); | ||
to(type: string, args?: newColorArgs): colorType; | ||
protected torgb(args: newColorArgs): rgb; | ||
protected toxyz(args: newColorArgs): xyz; | ||
protected toluv(args: newColorArgs): luv; | ||
} | ||
@@ -205,3 +242,5 @@ export declare class ypbpr extends colorType { | ||
constructor(y: number, pb: number, pr: number); | ||
to(type: string, args?: newColorArgs): colorType; | ||
protected torgb(args: newColorArgs): rgb; | ||
protected toypbpr(args: newColorArgs): ypbpr; | ||
protected toycbcr(args: newColorArgs): ycbcr; | ||
} | ||
@@ -213,3 +252,5 @@ export declare class ycbcr extends colorType { | ||
constructor(y: number, cb: number, cr: number); | ||
to(type: string, args?: newColorArgs): colorType; | ||
protected torgb(args: newColorArgs): rgb; | ||
protected toypbpr(args: newColorArgs): ypbpr; | ||
protected toycbcr(args: newColorArgs): ycbcr; | ||
} | ||
@@ -219,2 +260,3 @@ export declare class nm extends colorType { | ||
constructor(wavelength: number); | ||
protected torgb(args: newColorArgs): rgb; | ||
} | ||
@@ -224,2 +266,3 @@ export declare class kelvin extends colorType { | ||
constructor(k: number); | ||
protected torgb(args: newColorArgs): rgb; | ||
} |
@@ -367,3 +367,4 @@ import * as Colors from './Colors'; | ||
* | ||
* @param {number} wavelength Wavelength of light in nanometers (positive number) | ||
* @param {Colors.nm} nm Wavelength of light in nanometers (positive number) | ||
* @param {number} [gamma=0.8] Gamma adjustment | ||
* @param {boolean} [round=true] | ||
@@ -373,3 +374,3 @@ * @param {number} [bitDepth=8] | ||
*/ | ||
static nm2rgb(wavelength: number, gamma?: number, round?: boolean, bitDepth?: number): Colors.rgb; | ||
static nm2rgb(nm: Colors.nm, gamma?: number, round?: boolean, bitDepth?: number): Colors.rgb; | ||
/** | ||
@@ -381,8 +382,8 @@ * Convert a color temperature in Kelvin to RGB | ||
* | ||
* @param {number} temperature Color temperature in degrees Kelvin; must fall between 1000 and 40000 | ||
* @param {boolean} [round=true] | ||
* @param {number} [bitDepth=8] | ||
* @param {Colors.kelvin} kelvin Color temperature in degrees Kelvin; must fall between 1000 and 40000 | ||
* @param {boolean} [round=true] | ||
* @param {number} [bitDepth=8] | ||
* @return {Colors.rgb} | ||
*/ | ||
static kelvin2rgb(temperature: number, round?: boolean, bitDepth?: number): Colors.rgb; | ||
static kelvin2rgb(kelvin: Colors.kelvin, round?: boolean, bitDepth?: number): Colors.rgb; | ||
/** | ||
@@ -389,0 +390,0 @@ * Convert HEX to RGB |
@@ -1263,3 +1263,4 @@ "use strict"; | ||
* | ||
* @param {number} wavelength Wavelength of light in nanometers (positive number) | ||
* @param {Colors.nm} nm Wavelength of light in nanometers (positive number) | ||
* @param {number} [gamma=0.8] Gamma adjustment | ||
* @param {boolean} [round=true] | ||
@@ -1269,3 +1270,3 @@ * @param {number} [bitDepth=8] | ||
*/ | ||
Convert.nm2rgb = function (wavelength, gamma, round, bitDepth) { | ||
Convert.nm2rgb = function (nm, gamma, round, bitDepth) { | ||
if (gamma === void 0) { gamma = 0.8; } | ||
@@ -1277,23 +1278,23 @@ if (round === void 0) { round = true; } | ||
var b; | ||
if (wavelength >= 380 && wavelength < 440) { | ||
r = ((wavelength - 440) / (440 - 380)) * -1; | ||
if (nm.wavelength >= 380 && nm.wavelength < 440) { | ||
r = ((nm.wavelength - 440) / (440 - 380)) * -1; | ||
g = 0; | ||
b = 1; | ||
} | ||
else if (wavelength >= 440 && wavelength < 490) { | ||
else if (nm.wavelength >= 440 && nm.wavelength < 490) { | ||
r = 0; | ||
g = (wavelength - 440) / (490 - 440); | ||
g = (nm.wavelength - 440) / (490 - 440); | ||
b = 1; | ||
} | ||
else if (wavelength >= 510 && wavelength < 580) { | ||
r = (wavelength - 510) / (580 - 510); | ||
else if (nm.wavelength >= 510 && nm.wavelength < 580) { | ||
r = (nm.wavelength - 510) / (580 - 510); | ||
g = 1; | ||
b = 0; | ||
} | ||
else if (wavelength >= 580 && wavelength < 645) { | ||
else if (nm.wavelength >= 580 && nm.wavelength < 645) { | ||
r = 1; | ||
g = ((wavelength - 645) / (645 - 580)) * -1; | ||
g = ((nm.wavelength - 645) / (645 - 580)) * -1; | ||
b = 0; | ||
} | ||
else if (wavelength >= 645 && wavelength < 781) { | ||
else if (nm.wavelength >= 645 && nm.wavelength < 781) { | ||
r = 1; | ||
@@ -1310,10 +1311,10 @@ g = 0; | ||
// Let the intensity fall off near the vision limits | ||
if (wavelength >= 380 && wavelength < 420) { | ||
factor = 0.3 + 0.7 * (wavelength - 380) / (420 - 380); | ||
if (nm.wavelength >= 380 && nm.wavelength < 420) { | ||
factor = 0.3 + 0.7 * (nm.wavelength - 380) / (420 - 380); | ||
} | ||
else if (wavelength >= 420 && wavelength < 701) { | ||
else if (nm.wavelength >= 420 && nm.wavelength < 701) { | ||
factor = 1; | ||
} | ||
else if (wavelength >= 701 && wavelength < 781) { | ||
factor = 0.3 + 0.7 * (780 - wavelength) / (780 - 700); | ||
else if (nm.wavelength >= 701 && nm.wavelength < 781) { | ||
factor = 0.3 + 0.7 * (780 - nm.wavelength) / (780 - 700); | ||
} | ||
@@ -1346,11 +1347,11 @@ else { | ||
* | ||
* @param {number} temperature Color temperature in degrees Kelvin; must fall between 1000 and 40000 | ||
* @param {boolean} [round=true] | ||
* @param {number} [bitDepth=8] | ||
* @param {Colors.kelvin} kelvin Color temperature in degrees Kelvin; must fall between 1000 and 40000 | ||
* @param {boolean} [round=true] | ||
* @param {number} [bitDepth=8] | ||
* @return {Colors.rgb} | ||
*/ | ||
Convert.kelvin2rgb = function (temperature, round, bitDepth) { | ||
Convert.kelvin2rgb = function (kelvin, round, bitDepth) { | ||
if (round === void 0) { round = true; } | ||
if (bitDepth === void 0) { bitDepth = 8; } | ||
temperature /= 100; | ||
var k = kelvin.k / 100; | ||
var max = ((Math.pow(2, bitDepth)) - 1); | ||
@@ -1361,18 +1362,18 @@ var scalar = max / 255; | ||
var b; | ||
if (temperature <= 66) { | ||
r = bitDepth; | ||
g = 99.4708025861 * Math.log(temperature) - 161.1195681661; | ||
if (k <= 66) { | ||
r = max; | ||
g = 99.4708025861 * Math.log(k) - 161.1195681661; | ||
} | ||
else { | ||
r = 329.698727466 * Math.pow(temperature - 60, -0.1332047592); | ||
g = 288.1221695283 * Math.pow(temperature - 60, -0.0755148492); | ||
r = 329.698727466 * Math.pow(k - 60, -0.1332047592); | ||
g = 288.1221695283 * Math.pow(k - 60, -0.0755148492); | ||
} | ||
if (temperature >= 66) { | ||
b = bitDepth; | ||
if (k >= 66) { | ||
b = max; | ||
} | ||
else if (temperature <= 19) { | ||
else if (k <= 19) { | ||
b = 0; | ||
} | ||
else { | ||
b = 138.5177312231 * Math.log(temperature - 10) - 305.0447927307; | ||
b = 138.5177312231 * Math.log(k - 10) - 305.0447927307; | ||
} | ||
@@ -1379,0 +1380,0 @@ r *= scalar; |
@@ -13,5 +13,5 @@ import * as Colors from './Colors'; | ||
declare class Color implements colorDef { | ||
from(type: string, value: number[] | string, args?: newColorArgs): Colors.colorType; | ||
from(type: string, value: number[] | number | string, args?: newColorArgs): Colors.colorType; | ||
} | ||
declare const _default: Color; | ||
export = _default; |
@@ -52,2 +52,19 @@ "use strict"; | ||
} | ||
else if (typeof value === 'number') { | ||
switch (type) { | ||
case 'nm': | ||
case 'light': | ||
case 'nanometers': | ||
case 'nano': | ||
case 'wavelength': | ||
return new Colors.nm(value); | ||
case 'kelvin': | ||
case 'k': | ||
case 'temperature': | ||
case 'temp': | ||
return new Colors.kelvin(value); | ||
default: | ||
throw new Error('Unable to determine color type'); | ||
} | ||
} | ||
else { | ||
@@ -54,0 +71,0 @@ switch (type) { |
{ | ||
"name": "chromaticity-color-utilities", | ||
"version": "0.1.3-alpha", | ||
"version": "0.1.5-alpha", | ||
"description": "Color utilities for Node.js", | ||
"main": "src/main.js", | ||
"main": "dist/main.js", | ||
"scripts": { | ||
@@ -7,0 +7,0 @@ "test": "echo \"Error: no test specified\" && exit 1" |
808
README.md
# chromaticity-color-utilities | ||
Color utilities for Node.js. | ||
Conversion, modification, and color schemes of: RGB (at any bit depth), HSV, HSL, HSI, CYMK, YIQ, XYZ, xyY, L\*a\*b\*, L\*u\*v\*, Y'PbPr, and Y'CbCr. (More to follow.) | ||
Conversion, modification, and color schemes of: RGB (at any bit depth), HSV, HSL, HSI, CYMK, YIQ, XYZ, xyY, L\*a\*b\*, L\*u\*v\*, Y'PbPr, Y'CbCr, and more. | ||
@@ -12,2 +12,5 @@ ## Table of Contents | ||
* [RGB: Red, Green, Blue](#rgb--red-green-blue) | ||
* [HEX: Hexidecimal](#hex--hexidecimal) | ||
* [Rec. 709 RGB : HD video standard](#rec-709-rgb--hd-video-standard) | ||
* [Rec. 2020 RGB : UHD video standard](#rec-2020-rgb--uhd-video-standard) | ||
* [HSV: Hue, Saturation, Value](#hsv--hue-saturation-value) | ||
@@ -24,2 +27,4 @@ * [HSL: Hue, Saturation, Lightness](#hsl--hue-saturation-lightness) | ||
* [YCbCr: Digital video component signals](#ycbcr--digital-video-component-signals) | ||
* [NM: Wavelengths of Light](#nm--wavelengths-of-light) | ||
* [Kelvin: Color Temperature Approximation](#kelvin--color-temperature-approximation) | ||
* [Color Spaces and Standard Illuminants](#color-spaces-and-standard-illuminants) | ||
@@ -71,2 +76,3 @@ * [Modifying Colors](#modifying-colors) | ||
* [Compiling from Source](#compiling-from-source) | ||
* [To Do List](#to-do-list) | ||
@@ -144,9 +150,11 @@ ## Install | ||
Alpha is optional when available. If not defined, it will default to the maximum value for the given bit depth. When converting to a space that does not support alpha, it is ignored. If converting back, alpha will be set to full opacity. | ||
### RGB : Red, Green, Blue | ||
All values are between 0 and `((2 ** bitDepth) - 1)`. With a default bit depth of 8, values are within 0-255. A color with a bit depth of 16 will have values ranging from 0-65535. | ||
All values are between 0 and `(2 ** bitDepth) - 1`. With a default bit depth of 8, values are within 0-255. A color with a bit depth of 16 will have values ranging from 0-65535. | ||
** 8-bit color is sometimes referred to as 24-bit or 32-bit (8 bits per channel, with 32-bit including an alpha channel). This package uses the more correct implementation of 32-bit meaning 32 bits per channel, and so generally most use cases would fall between 8 and 16 bit color depth. | ||
** A special note: Adobe uses 15+1 bit depth for 16-bit color, where the last bit is simply added to the first 15 bits, hence the scale being | ||
** A special note: Adobe uses 15+1 bit depth for 16-bit color, where the last bit is simply added to the first 15 bits. | ||
@@ -163,3 +171,3 @@ ```ts | ||
//e.g. | ||
// e.g. | ||
let color1 = Color.from('rgb',[255, 0, 255]) | ||
@@ -171,2 +179,77 @@ let color3 = color2.to('rgb') | ||
### HEX : Hexidecimal | ||
May use string or numberical value. Strings are case-insensitive. Short form or long form may be used. # ignored if present. | ||
```ts | ||
Color.from('hex',hex) | ||
.to('hex') | ||
// e.g. | ||
let color1 = Color.from('hex', 'ff00ff') | ||
let color1 = Color.from('hex', '#FF00FF') | ||
let color1 = Color.from('hex', 0xFF00FF) | ||
let color3 = color2.to('hex') | ||
``` | ||
### Rec. 709 RGB : HD video standard | ||
Limits RGB color to video levels (16 - 235 for 8-bit or 64 to 940 for 10-bit). Input bit depth must be 8 or 10. Conversion to Y'PbPr and Y'CbCr will fail as this module does not yet have gamma adjustment implemented. | ||
This method does not currently support data levels. | ||
RGB values _may fall outside limits_. | ||
Alpha channel maintains data levels (0 - 255 / 0 - 1023). | ||
```ts | ||
Color.from('rec709rgb',[r, g, b, a?], { | ||
round: boolean, // optional, defaults to true | ||
bitDepth: number // optional, defaults to 8, must be 8 or 10 | ||
}) | ||
.to('rec709rgb', { | ||
round: boolean, // optional, defaults to true | ||
bitDepth: number // optional, defaults to 8, must be 8 or 10 | ||
}) | ||
// e.g. | ||
let color1 = Color.from('rec709rgb', [235, 16, 235]) | ||
let color1 = Color.from('rec709rgb', [940, 64, 940], { bitDepth: 10 }) | ||
let color3 = color2.to('rec709rgb') | ||
let color3 = color2.to('rec709rgb', { bitDepth: 10 }) | ||
``` | ||
### Rec. 2020 RGB : UHD video standard | ||
Limits RGB color to video levels (64 to 940 for 10-bit or 256 to 3760 for 12-bit). Input bit depth must be 10 or 12. Conversion to Y'PbPr and Y'CbCr will fail as this module does not yet have gamma adjustment implemented. | ||
This method does not currently support data levels. | ||
RGB values _may fall outside limits_. | ||
Alpha channel maintains data levels (0 - 1023 / 0 - 4096). | ||
```ts | ||
Color.from('rec2020rgb',[r, g, b, a?], { | ||
round: boolean, // optional, defaults to true | ||
bitDepth: number // optional, defaults to 10, must be 10 or 12 | ||
}) | ||
.to('rec2020rgb', { | ||
round: boolean, // optional, defaults to true | ||
bitDepth: number // optional, defaults to 10, must be 10 or 12 | ||
}) | ||
// e.g. | ||
let color1 = Color.from('rec2020rgb', [940, 64, 940]) | ||
let color1 = Color.from('rec2020rgb', [3760, 256, 3760], { bitDepth: 12 }) | ||
let color3 = color2.to('rec2020rgb') | ||
let color3 = color2.to('rec2020rgb', { bitDepth: 10 }) | ||
``` | ||
### HSV : Hue, Saturation, Value | ||
@@ -183,3 +266,3 @@ | ||
//e.g. | ||
// e.g. | ||
let color1 = Color.from('hsv',[300, 100, 100]) | ||
@@ -200,3 +283,3 @@ let color3 = color2.to('hsv') | ||
//e.g. | ||
// e.g. | ||
let color1 = Color.from('hsl',[300, 100, 50]) | ||
@@ -217,3 +300,3 @@ let color3 = color2.to('hsl') | ||
//e.g. | ||
// e.g. | ||
let color1 = Color.from('hsi',[300, 100, 67]) | ||
@@ -236,3 +319,3 @@ let color3 = color2.to('hsi') | ||
//e.g. | ||
// e.g. | ||
let color1 = Color.from('cmyk',[0, 100, 0, 0]) | ||
@@ -269,3 +352,3 @@ let color3 = color2.to('cmyk') | ||
//e.g. | ||
// e.g. | ||
let color1 = Color.from('yiq',[105, 59, 128]) | ||
@@ -300,3 +383,3 @@ let color3 = color2.to('yiq') | ||
//e.g. | ||
// e.g. | ||
let color1 = Color.from('xyz',[0.5928939, 0.2848479, 0.969638]) | ||
@@ -328,3 +411,3 @@ let color3 = color2.to('xyz') | ||
//e.g. | ||
// e.g. | ||
let color1 = Color.from('xyy',[0.3209377411185291, 0.1541902211986945, 0.2848479]) | ||
@@ -364,3 +447,3 @@ let color3 = color2.to('xyy') | ||
//e.g. | ||
// e.g. | ||
let color1 = Color.from('lab',[ | ||
@@ -400,3 +483,3 @@ 60.32421212836874, | ||
//e.g. | ||
// e.g. | ||
let color1 = Color.from('luv',[ | ||
@@ -427,9 +510,12 @@ 60.32421212836874, | ||
YPbPr conversions require Kb and Kr constants with the exception of converting to YCbCr. These values are not yet included in this package. | ||
* Kb = constant defined from target color space, such that Kb + Kr + Kg = 1 | ||
* Kr = constant defined from target color space, such that Kb + Kr + Kg = 1 | ||
Kb and Kr constants are not yet included in this package. | ||
```ts | ||
Color.from('ypbpr', [y, pb, pr]) | ||
Color.from('ypbpr', [y, pb, pr], { | ||
kb: number, // REQUIRED | ||
kr: number // REQUIRED | ||
}) | ||
@@ -449,3 +535,3 @@ .to('ypbpr',{ | ||
//e.g. | ||
// e.g. | ||
let color1 = Color.from('ypbpr',[ | ||
@@ -482,4 +568,11 @@ 0.2848, | ||
Upper and lower bounds vary with color space. It's recommended to always supply these values. | ||
```ts | ||
Color.from('ycbcr', [y, cb, cr]) | ||
Color.from('ycbcr', [y, cb, cr], { | ||
yLower: number, // optional, default = 16, lower bounds of Y' | ||
yUpper: number, // optional, default = 235, upper bounds of Y' | ||
cLower: number, // optional, default = 16, lower bounds of Cb and Cr | ||
cUpper: number // optional, default = 240, upper bounds of Cb and Cr | ||
) | ||
@@ -499,3 +592,3 @@ .to('ycbcr',{ | ||
//e.g. | ||
// e.g. | ||
let color1 = Color.from('ycbcr', [73, 226, 243]) | ||
@@ -515,2 +608,26 @@ let color3 = color2.to('ycbcr',{ | ||
### NM : Wavelengths of light | ||
This is a one-way approximation and is hugely perceptual. There is no `.to('nm')` method option. | ||
```ts | ||
Color.from('nm', wavelength) | ||
// e.g. | ||
let color1 = Color.from('nm',600).to('rgb') | ||
// rgb { r: 255, g: 190, b: 0, a: 255, bitDepth: 8, max: 255 } | ||
``` | ||
### Kelvin : Color Temperature Approximation | ||
This is a one-way approximatin. There is no `.to('kelvin')` method option. | ||
```ts | ||
Color.from('kelvin', degrees) | ||
// e.g. | ||
let color1 = Color.from('kelvin',3500).to('rgb') | ||
// rgb { r: 255, g: 193, b: 141, a: 255, bitDepth: 8, max: 255 } | ||
``` | ||
## Color Spaces and Standard Illuminants | ||
@@ -552,3 +669,3 @@ | ||
//e.g. | ||
// e.g. | ||
let color4 = Color.from('rgb',[255,0,0]).modify('blend', { | ||
@@ -587,5 +704,5 @@ with: Color.from('hex','00ff00') | ||
```ts | ||
color.scheme(type: string) | ||
.scheme(type: string) | ||
// or | ||
color.scheme(type: string, { | ||
.scheme(type: string, { | ||
angle: number // optional, hue shift angle in degrees | ||
@@ -714,431 +831,514 @@ }) | ||
``` | ||
X' = X / ((2 ** bitRate) - 1) | ||
X = X' * ((2 ** bitRate) - 1) | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/normalizing-xp.png) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/normalizing-x.png) | ||
### RGB to HSV | ||
``` | ||
V = max(R,G,B) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-hsv-v.png) | ||
C = V - min(R,G,B) | ||
C = chroma | ||
S = | 0 if V = 0 | ||
| C / V otherwise | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-hsv-c.png) | ||
| 0 if C = 0 | ||
H = | (G - B) / C if V = R | ||
| (B - R) / C if V = G | ||
| (R - G) / C if V = B | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-hsv-s.png) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-hsv-h.png) | ||
### HSV to RGB | ||
``` | ||
p = V * (1 - S) | ||
q = V * (1 - S * H) | ||
t = V * (1 - S * (1 - H)) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsv-rgb-p.png) | ||
| (V,V,V) if S = 0 | ||
| (V,t,p) if H < 1 | ||
| (q,V,p) if 1 < H <= 2 | ||
(R,G,B) = | (p,V,t) if 2 < H <= 3 | ||
| (p,q,V) if 3 < H <= 4 | ||
| (t,p,V) if 4 < H <= 5 | ||
| (V,p,q) otherwise | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsv-rgb-q.png) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsv-rgb-t.png) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsv-rgb-rgb.png) | ||
<!-- | ||
(R,G,B) = | ||
\begin{cases} | ||
(V,V,V) & \text{ if } S = 0 \\ | ||
(V,t,p) & \text{ if } H < 1 \\ | ||
(q,V,p) & \text{ if } 1 < H \leq 2 \\ | ||
(p,V,t) & \text{ if } 2 < H \leq 3 \\ | ||
(p,q,V) & \text{ if } 3 < H \leq 4 \\ | ||
(t,p,V) & \text{ if } 4 < H \leq 5 \\ | ||
(V,p,q) & \text{ otherwise } \\ | ||
\end{cases} | ||
--> | ||
### RGB to HSL | ||
``` | ||
V = max(R,G,B) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-hsv-v.png) | ||
C = V - min(R,G,B) | ||
C = chroma | ||
L = V - C / 2 | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-hsv-c.png) | ||
S = | 0 if L = 0 or L = 1 | ||
| (V - L) / min(L, 1 - L) otherwise | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-hsl-l.png) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-hsl-s.png) | ||
### HSL to RGB | ||
``` | ||
R,G,B = V if S = 0 | ||
C = chroma | ||
otherwise | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsl-rgb-c.png) | ||
C = (1 - |2L - 1|) * S | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsl-rgb-x.png) | ||
x = C * (1 - |H mod 2 - 1|) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsl-rgb-r1g1b1.png) | ||
| (0,0,0) if H undefined | ||
| (C,x,0) if 0 < H <= 1 | ||
| (x,C,0) if 1 < H <= 2 | ||
(R1,G1,B1) = | (0,C,x) if 2 < H <= 3 | ||
| (0,x,C) if 3 < H <= 4 | ||
| (x,0,C) if 4 < H <= 5 | ||
| (C,0,x) if 5 < H <= 6 | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsl-rgb-m.png) | ||
m = L - C / 2 | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsl-rgb-rgb.png) | ||
(R,G,B) = (R1 + m, G1 + m, B1 + m) | ||
``` | ||
<!-- | ||
(R_{1},G_{1},B_{1}) = | ||
\begin{cases} | ||
(0,0,0) & \text{ if } H \: \mathrm{undefined} \\ | ||
(C,x,0) & \text{ if } 0 < H \leq 1 \\ | ||
(x,C,0) & \text{ if } 1 < H \leq 2 \\ | ||
(0,C,x) & \text{ if } 2 < H \leq 3 \\ | ||
(0,x,C) & \text{ if } 3 < H \leq 4 \\ | ||
(x,0,C) & \text{ if } 4 < H \leq 5 \\ | ||
(C,0,x) & \text{ if } 5 < H \leq 6 \\ | ||
\end{cases} | ||
--> | ||
### RGB to HSI | ||
``` | ||
V = max(R,G,B) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-hsv-v.png) | ||
C = V - min(R,G,B) | ||
C = chroma | ||
| 0 if C = 0 | ||
H = | ((G - B) / C) mod 6 if V = R | ||
| ((B - R) / C) + 2 if V = G | ||
| ((R - G) / C) + 4 if V = B | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-hsv-c.png) | ||
I = | 0 if C = 0 | ||
| (R + G + B) * (1 / 3) otherwise | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-hsi-h.png) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-hsi-i.png) | ||
<!-- | ||
H=\begin{cases} | ||
0 & \text{ if } C=0 \\ | ||
\frac{G - B}{C} \: \mathrm{ mod } \: 6 & \text{ if } V=R \\ | ||
\frac{B - R}{C} + 2 & \text{ if } V=G \\ | ||
\frac{R - G}{C} + 4 & \text{ if } V=B \\ | ||
\end{cases} | ||
I=\begin{cases} | ||
0 & \text{ if } C=0 \\ | ||
(R + G + B) \cdot \frac{1}{3} & \text{ otherwise } | ||
\end{cases} | ||
--> | ||
### HSI to RGB | ||
``` | ||
z = 1 - |H mod 2 - 1| | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsi-rgb-z.png) | ||
C = (3I * S) / (1 + z) | ||
C = chroma | ||
x = C * z | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsi-rgb-c.png) | ||
| (0,0,0) if H undefined | ||
| (C,x,0) if 0 < H <= 1 | ||
| (x,C,0) if 1 < H <= 2 | ||
(R1,G1,B1) = | (0,C,x) if 2 < H <= 3 | ||
| (0,x,C) if 3 < H <= 4 | ||
| (x,0,C) if 4 < H <= 5 | ||
| (C,0,x) if 5 < H <= 6 | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsi-rgb-x.png) | ||
m = I * (1 - S) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsl-rgb-r1g1b1.png) | ||
(R,G,B) = (R1 + m, G1 + m, B1 + m) | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsi-rgb-m.png) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsl-rgb-rgb.png) | ||
### HSV to HSL | ||
``` | ||
L = V * (1 - S / 2) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsv-hsl-l.png) | ||
S = | 0 if L = 0 or L = 1 | ||
| (V - L) / min(L, 1 - L) otherwise | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsv-hsl-s.png) | ||
### HSL to HSV | ||
``` | ||
V = L * S * min(L, 1 - L) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsl-hsv-v.png) | ||
S = | 0 if V = 0 | ||
| 2 * (1 - L / V) otherwise | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/hsl-hsv-s.png) | ||
### RGB to CMYK | ||
``` | ||
K = 1 - max(R,G,B) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-cmyk-kcmy.png) | ||
C = | 0 if K = 1 | ||
| (1 - R - K) / (1 - K) otherwise | ||
M = | 0 if K = 1 | ||
| (1 - G - K) / (1 - K) otherwise | ||
Y = | 0 if K = 1 | ||
| (1 - B - K) / (1 - K) otherwise | ||
``` | ||
<!-- | ||
\begin{align*} | ||
K &= 1 - max(R,G,B)\\ | ||
C &= | ||
\begin{cases} | ||
0 & \text{ if } K=1 \\ | ||
\frac{1 - R - K}{1 - K} & \text{ otherwise } | ||
\end{cases} | ||
\\ | ||
M &= | ||
\begin{cases} | ||
0 & \text{ if } K=1 \\ | ||
\frac{1 - G - K}{1 - K} & \text{ otherwise } | ||
\end{cases} | ||
\\ | ||
Y &= | ||
\begin{cases} | ||
0 & \text{ if } K=1 \\ | ||
\frac{1 - B - K}{1 - K} & \text{ otherwise } | ||
\end{cases} | ||
\\ | ||
\end{align*} | ||
--> | ||
### CMYK to RGB | ||
``` | ||
R = (1 - C) * (1 - K) | ||
G = (1 - M) * (1 - K) | ||
B = (1 - Y) * (1 - K) | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/cmyk-rgb-rgb.png) | ||
### RGB to YIQ | ||
``` | ||
[Y] [0.299 0.587 0.114 ] [R] | ||
[I] = [0.5959 -0.2746 -0.3213] * [G] | ||
[Q] [0.2115 -0.5227 0.3112] [B] | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-yiq-yiq.png) | ||
Y ∈ [0,1] | ||
I ∈ [-0.5957,0.5957] | ||
Q ∈ [-0.5226,0.5226] | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-yiq-in.png) | ||
or, normalized | ||
<!-- | ||
\begin{bmatrix} | ||
Y\\ | ||
I\\ | ||
Q | ||
\end{bmatrix} = | ||
\begin{bmatrix} | ||
0.299 & 0.587 & 0.114 \\ | ||
0.5959 & -0.2746 & -0.3213 \\ | ||
0.2115 & -0.5227 & 0.3112 | ||
\end{bmatrix} | ||
\begin{bmatrix} | ||
R\\ | ||
G\\ | ||
B | ||
\end{bmatrix} | ||
Y ∈ [0,255] | ||
I ∈ [-128, 128] | ||
Q ∈ [-128, 128] | ||
``` | ||
\begin{align*} | ||
Y &\in [0,1]\\ | ||
I &\in [-0.5957,0.5957] \\ | ||
Q &\in [-0.5226,0.5226] \\ | ||
\text{or}&,\text{normalized} \\ | ||
Y &\in [0,255]\\ | ||
I &\in [-128,128] \\ | ||
Q &\in [-128,128] \\ | ||
\end{align} | ||
--> | ||
### YIQ to RGB | ||
``` | ||
Y ∈ [0,1] | ||
I ∈ [-0.5957,0.5957] | ||
Q ∈ [-0.5226,0.5226] | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/yiq-rgb-in.png) | ||
[R] [1 0.956 0.621] [Y] | ||
[G] = [1 -0.272 -0.647] * [I] | ||
[B] [1 -1.106 1.703] [Q] | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/yiq-rgb-rgb.png) | ||
<!-- | ||
\begin{bmatrix} | ||
R\\ | ||
G\\ | ||
B | ||
\end{bmatrix} = | ||
\begin{bmatrix} | ||
1 & 0.956 & 0.621 \\ | ||
1 & -0.272 & -0.647 \\ | ||
1 & -1.106 & 1.703 | ||
\end{bmatrix} | ||
\begin{bmatrix} | ||
Y\\ | ||
I\\ | ||
Q | ||
\end{bmatrix} | ||
--> | ||
### RGB to XYZ | ||
M = 3x3 RGB to XYZ transformation matrix based on color space and standard illuminant reference white | ||
M = 3x3 RGB to XYZ transformation matrix based on color space and standard illuminant reference white. This transformation matrix is an inverse of the XYZ to RGB transformation matrix. | ||
#### sRGB | ||
``` | ||
for X = (R,G,B) | ||
X' = | X / 12.92 if X <= 0.04045 | ||
| ((X + 0.055) / 1.055) ^ 2.4 otherwise | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-xyz-srgb-xp.png) | ||
[X] [R'] | ||
[Y] = M * [G'] | ||
[Z] [B'] | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-xyz-xyz.png) | ||
#### L* | ||
``` | ||
κ = 903.3, CIE-K | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/cie-ek.png) | ||
for X = (R,G,B) | ||
X' = | 100 * (R / κ) if R <= 0.08 | ||
| ((R + 0.16) / 1.16) ^ 3 otherwise | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-xyz-ls.png) | ||
[X] [R'] | ||
[Y] = M * [G'] | ||
[Z] [B'] | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-xyz-xyz.png) | ||
<!-- | ||
\begin{align*} | ||
\text{for } X &= (R,G,B) \\ | ||
X' &= | ||
\begin{cases} | ||
100 \cdot \frac{X}{\kappa} & \text{ if } X \leq 0.08 \\ | ||
(\frac{R + 0.16}{1.16})^3 & \text{ otherwise } | ||
\end{cases} | ||
\end{align*} | ||
--> | ||
#### Other color spaces | ||
``` | ||
γ based on target color space | ||
gamma (γ) based on target color space | ||
for X = (R,G,B) | ||
X' = X ^ γ | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-xyz-gamma.png) | ||
[X] [R'] | ||
[Y] = M * [G'] | ||
[Z] [B'] | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-xyz-xyz.png) | ||
### XYZ to RGB | ||
M = 3x3 XYZ to RGB transformation matrix based on color space and standard illuminant reference white | ||
M = 3x3 XYZ to RGB transformation matrix based on color space and standard illuminant reference white. | ||
#### sRGB | ||
``` | ||
[R'] [X] | ||
[G'] = M * [Y] | ||
[B'] [Z] | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/xyz-rgb-rpgpbp.png) | ||
for X' = (R',G',B') | ||
X = | X' * 12.92 if X' <= 0.0031308 | ||
| (X' * 1.055) ^ (1 / 2.4) - 0.055 otherwise | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/xyz-rgb-srgb.png) | ||
#### L* | ||
``` | ||
[R'] [X] | ||
[G'] = M * [Y] | ||
[B'] [Z] | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/xyz-rgb-rpgpbp.png) | ||
ϵ = 0.008856, CIE-E | ||
κ = 903.3, CIE-K | ||
for X' = (R',G',B') | ||
X = | X' * κ / 100 if X' <= ϵ | ||
| 1.16 * X' ^ (1/3) - 0.16 otherwise | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/cie-ek.png) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/xyz-rgb-ls.png) | ||
<!-- | ||
\begin{align*} | ||
\text{for } X &= (R,G,B) \\ | ||
X &= | ||
\begin{cases} | ||
X' \cdot \frac{\kappa}{100} & \text{ if } X' \leq \epsilon \\ | ||
1.16 \cdot {X'}^\frac{1}{3} - 0.16 & \text{ otherwise } | ||
\end{cases} | ||
\end{align*} | ||
--> | ||
#### Other color spaces | ||
``` | ||
γ based on target color space | ||
gamma (γ) based on target color space | ||
[R'] [X] | ||
[G'] = M * [Y] | ||
[B'] [Z] | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/xyz-rgb-rpgpbp.png) | ||
for X' = (R',G',B') | ||
X = X' ^ (1 / γ) | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/xyz-rgb-gamma.png) | ||
<!-- | ||
\begin{align*} | ||
\text{for } X &= (R,G,B) \\ | ||
X &= | ||
{X'}^\frac{1}{\gamma} | ||
\end{align*} | ||
--> | ||
### XYZ to xyY | ||
``` | ||
x = X / (X + Y + Z) | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/xyz-xyy.png) | ||
y = Y / (X + Y + Z) | ||
<!-- | ||
\begin{align*} | ||
x &= \frac{X}{X + Y + Z} \\ | ||
y &= \frac{Y}{X + Y + Z} \\ | ||
Y &= Y | ||
\end{align*} | ||
--> | ||
Y = Y | ||
``` | ||
### xyY to XYZ | ||
``` | ||
X = (x * Y) / y | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/xyy-xyz.png) | ||
Y = Y | ||
<!-- | ||
\begin{align*} | ||
X &= \frac{x \cdot Y}{y} \\ | ||
Y &= Y \\ | ||
Z &= \frac{(1 - x - y) \cdot Y}{y} | ||
\end{align*} | ||
--> | ||
Z = ((1 - x - y) * Y) / y | ||
``` | ||
### XYZ to L\*a\*b\* | ||
``` | ||
W is a 1x3 reference white vector based on standard illuminant | ||
W is a 1x3 reference white vector based on standard illuminant. | ||
ϵ = 0.008856, CIE-E | ||
κ = 903.3, CIE-K | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/cie-ek.png) | ||
X' = X / W[0] | ||
Y' = Y / W[1] | ||
Z' = Z / W[2] | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/xyz-lab-p.png) | ||
f(n) = | n' ^ 1/3 if n > ϵ | ||
| (κ * n' + 16) / 116 otherwise | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/xyz-lab-fn.png) | ||
L* = 116 * f(Y) - 16 | ||
a* = 500 * (f(X) - f(Y)) | ||
b* = 200 * (f(Y) - f(Z)) | ||
``` | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/xyz-lab-lab.png) | ||
<!-- | ||
\begin{align*} | ||
X' &= \frac{X}{W_{R}} \\ | ||
Y' &= \frac{Y}{W_{G}} \\ | ||
Z' &= \frac{Z}{W_{B}} | ||
\end{align*} | ||
f(n) = \begin{cases} | ||
{n'}^\frac{1}{3} & \text{ if } n > \epsilon \\ | ||
\frac{\kappa \cdot n' + 16}{116} & \text{ otherwise } | ||
\end{cases} | ||
\begin{align*} | ||
L^* &= 116 \cdot f(Y) - 16\\ | ||
a^* &= 500 \cdot (f(X) - f(Y))\\ | ||
b^* &= 200 \cdot (f(Y) - f(Z)) | ||
\end{align*} | ||
--> | ||
### L\*a\*b\* to XYZ | ||
``` | ||
W is a 1x3 reference white vector based on standard illuminant | ||
W is a 1x3 reference white vector based on standard illuminant. | ||
ϵ = 0.008856, CIE-E | ||
κ = 903.3, CIE-K | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/cie-ek.png) | ||
L' = (L* + 16) / 116 | ||
a' = a* / 500 + L' | ||
b' = L' - b* / 200 | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/lab-xyz-labp.png) | ||
X' = | a' ^ 3 if a' ^ 3 > ϵ | ||
| (116 * a' - 16) / κ otherwise | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/lab-xyz-xyzp.png) | ||
Y' = | (L' ^ 3 if L* > κ * ϵ | ||
| L* * κ otherwise | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/lab-xyz-xyz.png) | ||
Z' = | b' ^ 3 if b' ^ 3 > ϵ | ||
| (116 * b' - 16) / κ otherwise | ||
<!-- | ||
\begin{align*} | ||
X' &= | ||
\begin{cases} | ||
a'^3 & \text{ if } a'^3 > \epsilon \\ | ||
\frac{116 \cdot a' - 16}{\kappa} & \text{ otherwise } | ||
\end{cases} | ||
\\ | ||
Y' &= | ||
\begin{cases} | ||
L'^3 & \text{ if } L^* > \kappa \cdot \epsilon \\ | ||
L^* \cdot \kappa & \text{ otherwise } | ||
\end{cases} | ||
\\ | ||
Z' &= | ||
\begin{cases} | ||
b'^3 & \text{ if } b'^3 > \epsilon \\ | ||
\frac{116 \cdot b' - 16}{\kappa} & \text{ otherwise } | ||
\end{cases} | ||
\end{align*} | ||
X = X' * W[0] | ||
Y = Y' * W[1] | ||
Z = Z' * W[2] | ||
``` | ||
\begin{align*} | ||
X &= X' \cdot W_{R} \\ | ||
Y &= Y' \cdot W_{G} \\ | ||
Z &= Z' \cdot W_{B} | ||
\end{align*} | ||
--> | ||
### XYZ to L\*u\*v\* | ||
``` | ||
W is a 1x3 reference white vector based on standard illuminant | ||
ϵ = 0.008856, CIE-E | ||
κ = 903.3, CIE-K | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/cie-ek.png) | ||
Y' = Y / W[1] | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/xyz-luv.png) | ||
d = X + 15 * Y + 3 * Z | ||
<!-- | ||
\begin{align*} | ||
Y' &= \frac{Y}{W_{G}} \\ | ||
\:\\ | ||
d &= X + 15Y + 3Z \\ | ||
\:\\ | ||
u' &= | ||
\begin{cases} | ||
0 & \text{ if } d=0 \\ | ||
\frac{4X}{d} & \text{ otherwise } | ||
\end{cases} \\ | ||
v' &= | ||
\begin{cases} | ||
0 & \text{ if } d=0 \\ | ||
\frac{9Y}{d} & \text{ otherwise } | ||
\end{cases} \\ | ||
\:\\ | ||
L^* &= | ||
\begin{cases} | ||
116 \cdot {Y'}^\frac{1}{3} & \text{ if } Y' > \epsilon \\ | ||
Y' \cdot \kappa & \text{ otherwise } | ||
\end{cases} \\ | ||
\:\\ | ||
u'_{r} &= \frac{4 \cdot W_{G}}{W_{R} + 15 \cdot W_{G} + 3 \cdot W_{B}} \\ | ||
v'_{r} &= \frac{9 \cdot W_{G}}{W_{R} + 15 \cdot W_{G} + 3 \cdot W_{B}} \\ | ||
\:\\ | ||
u^* &= L^* \cdot (u' - u'_{r}) \\ | ||
v^* &= L^* \cdot (v' - v'_{r}) | ||
\end{align*} | ||
--> | ||
u' = | 0 if d = 0 | ||
| 4X / d otherwise | ||
v' = | 0 if d = 0 | ||
| 9Y / d otherwise | ||
L* = | 116 * Y' ^ 1/3 if Y' > ϵ | ||
| Y' * κ otherwise | ||
u'r = (4 * W[1]) / (W[0] + 15 * W[1] + 3 * W[2]) | ||
v'r = (9 * W[1]) / (W[0] + 15 * W[1] + 3 * W[2]) | ||
u* = 13 * L* * (u' - u'r) | ||
v* = 13 * L* * (v' - v'r) | ||
``` | ||
### L\*u\*v\* to XYZ | ||
``` | ||
W is a 1x3 reference white vector based on standard illuminant | ||
ϵ = 0.008856, CIE-E | ||
κ = 903.3, CIE-K | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/cie-ek.png) | ||
Y = | ((L* + 16) / 116) ^ 3 if L* > κ * ϵ | ||
| L* / κ otherwise | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/luv-xyz.png) | ||
u0 = (4 * W[0]) / (W[0] + 15 * W[1] + 3 * W[2]) | ||
v0 = (9 * W[0]) / (W[0] + 15 * W[1] + 3 * W[2]) | ||
<!-- | ||
\begin{align*} | ||
Y &= | ||
\begin{cases} | ||
(\frac{L^* + 16}{116})^{1/3} & \text{ if } L^* > \kappa \cdot \epsilon \\ | ||
\frac{L^*}{\kappa} & \text{ otherwise } | ||
\end{cases} | ||
\\ | ||
\:\\ | ||
u_{0} &= \frac{4 \cdot W_{R}}{W_{R} + 15 \cdot W_{G} + 3 \cdot W_{B}} \\ | ||
v_{0} &= \frac{9 \cdot W_{R}}{W_{R} + 15 \cdot W_{G} + 3 \cdot W_{B}} \\ | ||
\:\\ | ||
a &= \frac{1}{3} \cdot \frac{52 \cdot L^*}{u^* + 13 \cdot L^* \cdot u_{0}} - 1 \\ | ||
b &= -5Y \\ | ||
c &= -\frac{1}{3} \\ | ||
d &= Y \cdot \frac{39 \cdot L^*}{v^* + 13 \cdot L^* \cdot v_{0}} - 5 \\ | ||
\:\\ | ||
X &= \frac{d - b}{a - c} \\ | ||
Z &= X \cdot a + b | ||
\end{align*} | ||
--> | ||
a = 1/3 * (((52 * L*) / (u* + 13 * L* * u0))) - 1) | ||
b = -5Y | ||
c = -1/3 | ||
d = Y * (((39 * L*) / (v* + 13 * L* * v0)) - 5) | ||
X = (d - b) / (a - c) | ||
Z = X * a + b | ||
``` | ||
### RGB to YPbPr | ||
``` | ||
Kb and Kr constants defined from target color space | ||
Kg = 1 - Kb - Kr | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/rgb-ypbpr.png) | ||
Y = Kr * R + Kg * G + Kb * B | ||
<!-- | ||
\begin{align*} | ||
Kg &= 1 - Kb - Kr \\ | ||
\:\\ | ||
Y &= Kr \cdot R + Kg \cdot G + Kb \cdot B\\ | ||
Pb &= 0.5 \cdot \frac{B - Y}{1 - Kb}\\ | ||
Pr &= 0.5 \cdot \frac{R - Y}{1 - Kr}\\ | ||
\end{align*} | ||
--> | ||
Pb = 0.5 * ((B - Y) / (1 - Kb)) | ||
Pr = 0.5 * ((R - Y) / (1 - Kr)) | ||
``` | ||
### YPbPr to YCbCr | ||
``` | ||
Scaling bounds given by conversion method / target space. Such as: | ||
Scaling bounds given by conversion method / target space. Typical bounds might be 0-255 for all values for JPEG target or 16-235 for Y and 16-245 for Cb and Cr for Rec. 709 target. | ||
Y scaled to: 0 - 255 JPEG | ||
16 - 235 Rec709 | ||
Cb, Cr scaled to: 0 - 255 JPEG | ||
16 - 245 Rec709 | ||
``` | ||
### YCbCr to YPbPr | ||
``` | ||
Y scaled to: 0 - 1 | ||
Pb, Pr scaled to: -0.5 - 0.5 | ||
``` | ||
Y is scaled to 0-1, Cb and Cr are scaled such that Pb and Pr are between -0.5 and 0.5. | ||
### YPbPr to RGB | ||
``` | ||
Kb and Kr constants defined from target color space | ||
Kg = 1 - Kb - Kr | ||
![](https://raw.githubusercontent.com/reiniiriarios/chromaticity-color-utilities/master/math/ypbpr-rgb.png) | ||
R = Y + (2 - 2Kr) * Pr | ||
G = Y + (-1 * (Kb / Kg) * (2 - 2Kb)) * Pb + (-1 * (Kr / Kg) * (2 - 2Kr)) * Pr | ||
B = Y + (2 - 2Kb) * Pb | ||
``` | ||
<!-- | ||
\begin{align*} | ||
Kg &= 1 - Kb - Kr \\ | ||
\:\\ | ||
Pb_{0} &= (-1 \cdot \frac{Kb}{Kg} \cdot (2 - 2Kb)) \cdot Pb \\ | ||
Pr_{0} &= (-1 \cdot \frac{Kr}{Kg} \cdot (2 - 2Kr)) \cdot Pr \\ | ||
\:\\ | ||
R &= Y + (2 - 2Kr) \cdot Pr \\ | ||
G &= Y + Pb_{0} + Pr_{0} | ||
\\ | ||
B &= Y + (2 - 2Kb) \cdot Pb | ||
\end{align*} | ||
--> | ||
@@ -1153,2 +1353,14 @@ ## Compiling from Source | ||
`tsc` | ||
`tsc` | ||
## To Do List | ||
* Gamma adjustment modification | ||
* Auto-gamma adjustment and conversion for rec709, rec2020, and jpeg to/from ypbpr | ||
* note to self: rec709 does gamma conversion before while rec2020 does gamma conversion after when converting to ypbpr (I think) | ||
* Lighten and darken colors | ||
* Saturate and desaturate colors | ||
* Create color schemes / gradient schemes based on tints and shades | ||
* Generate gradients given two colors | ||
* Generate triangular gradients based on three colors | ||
* Modification methods that retain luma |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1343
251600
5048