Ich habe eine Hex-Farbe, z. B. #F4F8FB
(oder rgb(244, 248, 251)
), die ich in eine möglichst transparente RGBA-Farbe umwandeln möchte (wenn sie über Weiß angezeigt wird). Sinn ergeben? Ich suche nach einem Algorithmus oder zumindest nach einer Idee, wie das geht.
Beispielsweise:
rgb( 128, 128, 255 ) --> rgba( 0, 0, 255, .5 )
rgb( 152, 177, 202 ) --> rgba( 50, 100, 150, .5 ) // can be better(lower alpha)
Ideen?
FYI-Lösung basierend auf Guffas Antwort:
function RGBtoRGBA(r, g, b){
if((g == null) && (typeof r === 'string')){
var hex = r.replace(/^\s*#|\s*$/g, '');
if(hex.length === 3){
hex = hex.replace(/(.)/g, '$1$1');
}
r = parseInt(hex.substr(0, 2), 16);
g = parseInt(hex.substr(2, 2), 16);
b = parseInt(hex.substr(4, 2), 16);
}
var min, a = (255 - (min = Math.min(r, g, b))) / 255;
return {
r : r = 0|(r - min) / a,
g : g = 0|(g - min) / a,
b : b = 0|(b - min) / a,
a : a = (0|1000*a)/1000,
rgba : 'rgba(' + r + ', ' + g + ', ' + b + ', ' + a + ')'
};
}
RGBtoRGBA(204, 153, 102) == RGBtoRGBA('#CC9966') == RGBtoRGBA('C96') ==
{
r : 170,
g : 85 ,
b : 0 ,
a : 0.6,
rgba : 'rgba(170, 85, 0, 0.6)'
}
javascript
colors
css
rgba
Mark Kahn
quelle
quelle
Antworten:
Nehmen Sie die niedrigste Farbkomponente und konvertieren Sie diese in einen Alpha-Wert. Skalieren Sie dann die Farbkomponenten, indem Sie die niedrigsten subtrahieren und durch den Alpha-Wert dividieren.
Beispiel:
Also,
rgb(152, 177, 202)
zeigt alsrgba(0, 62, 123, .404)
.Ich habe in Photoshop überprüft, ob die Farben tatsächlich perfekt übereinstimmen.
quelle
.404
), konnte aber die Zahlen nicht ganz zum Laufen bringen.0..255
in skaliert0..1
und invertiert. Verwenden1.0 - 152 / 255
würde auch funktionieren. Die Farbkomponenten Umwandlung skaliert einfach ausn..255
zu ,0..255
won
die niedrigste Komponente.Sei r, g und b die Eingabewerte und r ', g', b 'und a' die Ausgabewerte, alle skaliert (vorerst, da dies die Mathematik schöner macht) zwischen 1 und 0. Dann durch die Formel zum Überlagern von Farben:
Die Begriffe 1 - a 'stellen den Hintergrundbeitrag dar, und die anderen Begriffe stellen den Vordergrund dar. Mach etwas Algebra:
Intuitiv scheint der minimale Farbwert der begrenzende Faktor für das Problem zu sein. Binden Sie ihn also an m:
Setzen Sie den entsprechenden Ausgabewert m 'auf Null, um die Transparenz zu maximieren:
Also, in Javascript (übersetzt von 1 bis 255 auf dem Weg):
Beachten Sie, dass ich davon ausgehe, dass a 'hier Deckkraft ist. Es ist trivial, es in Transparenz zu ändern - entfernen Sie einfach die "1 -" aus der Formel für a '. Zu beachten ist, dass dies keine exakten Ergebnisse zu liefern scheint - es wurde angegeben, dass die Opazität für das oben angegebene Beispiel 0,498 betrug (128, 128, 255). Dies ist jedoch sehr nahe.
quelle
[255 * (r/255 - 1) / a + 1 * 255, ...] == [(255*r/255 - 255 * 1) / a + 255, ...] == [(r - 255) / a + 255, ...]
Ich würde auf RGB <-> HSL-Konvertierung schauen. Dh Leuchtkraft == Menge Weiß == Menge Transparenz.
In Ihrem Beispiel
rgb( 128, 128, 255 )
müssen wir die RGB-Werte0
zuerst um den maximalen Betrag verschieben, dh umrgb( 0, 0, 128 )
- das wäre unsere Farbe mit so wenig Weiß wie möglich. Und danach berechnen wir mithilfe der Formel für die Luminanz die Menge an Weiß, die wir zu unserer dunklen Farbe hinzufügen müssen, um die ursprüngliche Farbe zu erhalten - das wäre unser Alpha:Hoffe das macht Sinn. :) :)
quelle
Für diejenigen unter Ihnen, die SASS / SCSS verwenden, habe ich eine kleine SCSS-Funktion geschrieben, damit Sie den von @Guffa beschriebenen Algorithmus problemlos verwenden können
quelle
Ich beschreibe nur eine Idee für den Algorithmus, keine vollständige Lösung:
Grundsätzlich haben Sie drei Zahlen
x
,y
,z
und Sie suchen drei neue Nummernx'
,y'
,z'
und ein Multiplikatora
im Bereich von [0,1] , so dass:Dies wird in Einheiten geschrieben, in denen die Kanäle auch Werte im Bereich [0,1] annehmen. Bei diskreten 8-Bit-Werten wäre dies ungefähr so:
Darüber hinaus möchten Sie den größtmöglichen Wert
a
. Sie können lösen:Usw. In reellen Werten hat dies unendlich viele Lösungen. Stecken Sie einfach eine beliebige reelle Zahl ein
a
, aber das Problem besteht darin, eine Zahl zu finden, für die der Diskretisierungsfehler minimal ist.quelle
Dies sollte es tun:
quelle
y
und eingeführt wurde(y-x)
. Das255 / (y-x)
zwingt falsch die größte Zahl an255
, so dass Sie immer mit einem einzigen Ende würde0
, eine einzige255
und dann eine andere Nummer:0, 22, 255
,255, 0, 55
usw .../a
und dann stimmt es mit der richtigen Antwort überein.Die Top-Antwort hat bei niedrigen Farbkomponenten bei mir nicht funktioniert. Beispielsweise wird das korrekte Alpha nicht berechnet, wenn die Farbe # 80000 ist. Technisch sollte es mit alpha 0.5 in # ff0000 kommen. Um dies zu beheben, müssen Sie RGB -> HSL -> RGBA-Konvertierung verwenden. Dies ist Pseudocode, um die richtigen Werte zu erhalten:
"newRgb" enthält den Wert der neu eingestellten Farbe und verwendet die Variable "alpha", um die Transparenz zu steuern.
quelle
#800000
undrgba( 255, 0, 0, .5 )
sind nicht annähernd die gleiche Farbe. Der erste wäre dunkelrot, der zweite lachsfarben. Wenn sie nicht über Schwarz angezeigt werden, sind sie wahrscheinlich gleich.