Ich habe heute eine ähnliche Aufgabe in JavaScript gelöst. Ich habe mich für diese getPerceivedLightness(rgb)
Funktion für eine HEX RGB-Farbe entschieden. Es handelt sich um den Helmholtz-Kohlrausch-Effekt über die Fairchild- und Perrotta-Formel zur Helligkeitskorrektur.
/**
* Konvertiert RGB-Farbe in den CIE 1931 XYZ-Farbraum.
* https://www.image-engineering.de/library/technotes/958-how-to-convert-between-srgb-and-ciexyz
* @param {string} hex
* @return {number[]}
*/
export function rgbToXyz(hex) {
const [r, g, b] = hexToRgb(hex).map(_ => _ / 255).map(sRGBtoLinearRGB)
const X = 0.4124 * r + 0.3576 * g + 0.1805 * b
const Y = 0.2126 * r + 0.7152 * g + 0.0722 * b
const Z = 0.0193 * r + 0.1192 * g + 0.9505 * b
// Aus irgendeinem Grund werden X, Y und Z mit 100 multipliziert.
return [X, Y, Z].map(_ => _ * 100)
}
/**
* Hebt die Gamma-Korrektur einer RGB-codierten Farbe auf.
* https://en.wikipedia.org/wiki/SRGB#Specification_of_the_transformation
* https://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color
* @param {number}
* @return {number}
*/
function sRGBtoLinearRGB(color) {
// Übergeben Sie dieser Funktion einen dezimalen sRGB-gamma-codierten Farbwert
// zwischen 0,0 und 1,0, und sie gibt einen linearisierten Wert zurück.
if (color <= 0,04045) {
return color / 12,92
} else {
return Math.pow((color + 0,055) / 1,055, 2,4)
}
}
/**
* Konvertiert Hex-Farbe in RGB.
* https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
* @param {string} hex
* @return {number[]} [rgb]
*/
function hexToRgb(hex) {
const match = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
if (match) {
match.shift()
return match.map(_ => parseInt(_, 16))
}
}
/**
* Konvertiert CIE 1931 XYZ-Farben in CIE L*a*b*.
* Die Konversionsformel stammt von .
* https://github.com/cangoektas/xyz-to-lab/blob/master/src/index.js
* @param {number[]} color Die zu konvertierende CIE 1931 XYZ-Farbe, die sich auf
* das D65/2°-Standardbeleuchtung bezieht.
* @returns {number[]} Die Farbe im CIE L*a*b*-Farbraum.
*/
// X, Y, Z einer "D65" Lichtquelle.
// "D65" ist eine Standard-Tageslichtlichtquelle von 6500K.
// https://en.wikipedia.org/wiki/Illuminant_D65
const D65 = [95,047, 100, 108,883]
export function xyzToLab([x, y, z]) {
[x, y, z] = [x, y, z].map((v, i) => {
v = v / D65[i]
return v > 0,008856 ? Math.pow(v, 1 / 3) : v * 7,787 + 16 / 116
})
const l = 116 * y - 16
const a = 500 * (x - y)
const b = 200 * (y - z)
return [l, a, b]
}
/**
* Konvertiert Lab-Farbraum in Luminance-Chroma-Hue-Farbraum.
* http://www.brucelindbloom.com/index.html?Eqn_Lab_to_LCH.html
* @param {number[]}
* @return {number[]}
*/
export function labToLch([l, a, b]) {
const c = Math.sqrt(a * a + b * b)
const h = abToHue(a, b)
return [l, c, h]
}
/**
* Konvertiert a und b des Lab-Farbraums in Hue des LCH-Farbraums.
* https://stackoverflow.com/questions/53733379/conversion-of-cielab-to-cielchab-not-yielding-correct-result
* @param {number} a
* @param {number} b
* @return {number}
*/
function abToHue(a, b) {
if (a >= 0 && b === 0) {
return 0
}
if (a < 0 && b === 0) {
return 180
}
if (a === 0 && b > 0) {
return 90
}
if (a === 0 && b < 0) {
return 270
}
let xBias
if (a > 0 && b > 0) {
xBias = 0
} else if (a < 0) {
xBias = 180
} else if (a > 0 && b < 0) {
xBias = 360
}
return radiansToDegrees(Math.atan(b / a)) + xBias
}
function radiansToDegrees(radians) {
return radians * (180 / Math.PI)
}
function degreesToRadians(degrees) {
return degrees * Math.PI / 180
}
/**
* Sättigte Farben erscheinen dem menschlichen Auge heller.
* Das nennt man den Helmholtz-Kohlrausch-Effekt.
* Fairchild und Pirrotta haben eine Formel entwickelt, um
* einen Korrekturfaktor für diesen Effekt zu berechnen.
* "Color Quality of Semiconductor and Conventional Light Sources":
* https://books.google.ru/books?id=ptDJDQAAQBAJ&pg=PA45&lpg=PA45&dq=fairchild+pirrotta+correction&source=bl&ots=7gXR2MGJs7&sig=ACfU3U3uIHo0ZUdZB_Cz9F9NldKzBix0oQ&hl=ru&sa=X&ved=2ahUKEwi47LGivOvmAhUHEpoKHU_ICkIQ6AEwAXoECAkQAQ#v=onepage&q=fairchild%20pirrotta%20correction&f=false
* @return {number}
*/
function getLightnessUsingFairchildPirrottaCorrection([l, c, h]) {
const l_ = 2,5 - 0,025 * l
const g = 0,116 * Math.abs(Math.sin(degreesToRadians((h - 90) / 2))) + 0,085
return l + l_ * g * c
}
export function getPerceivedLightness(hex) {
return getLightnessUsingFairchildPirrottaCorrection(labToLch(xyzToLab(rgbToXyz(hex))))
}
10 Stimmen
Die wahrgenommene Helligkeit ist das, wonach ich suche, danke.
0 Stimmen
Ich habe [diesen Code][1] (geschrieben in C#) gefunden, der hervorragende Arbeit bei der Berechnung der "Helligkeit" einer Farbe leistet. In diesem Szenario versucht der Code festzustellen, ob weißer oder schwarzer Text über der Farbe platziert werden soll. [1]:nbdtech.com/Blog/archive/2008/04/27/…
2 Stimmen
Es gibt einen guten Artikel (Farbmanipulation in .NET - Teil 1) über Farbräume und deren Konvertierungen, einschließlich sowohl Theorie als auch Code (C#). Für die Antwort schauen Sie sich das Thema Konvertierung zwischen Modellen im Artikel an.
0 Stimmen
Sehen Sie meine Antwort, aber wirklich einfach ist: Helligkeit = 0,2*r + 0,7*g + 0,1*b