HSL zu RGB Werten


17

Der Hauptzweck des RGB-Farbmodells (Rot, Grün, Blau) besteht in der Erfassung, Darstellung und Anzeige von Bildern in elektronischen Systemen wie Fernsehgeräten und Computern

HSL (Hue Saturation Lightness) ist ein alternatives Farbmodell, das in den 1970er Jahren von Computergrafik-Forschern entwickelt wurde, um die Wahrnehmung von Farbmerkmalen durch das menschliche Sehvermögen genauer abzustimmen

Hier sind die Wiki-Artikel für RGB und HSL . Es ist üblich, dass Grafikprogramme die Berechnungen in HSL ausführen und später in das bevorzugte Format für die meisten Bildschirme konvertieren: RGB.

Die Aufgabe besteht darin, eine Funktion / ein Programm zu schreiben, die / das HSL als Eingabe und Ausgabe von RGB verwendet.

Sie können Ihre bevorzugte Darstellung für die E / A auswählen, sofern diese übereinstimmt.

Zum Beispiel kann sie ein Array / Tupels mit 3 Elementen oder ein Objekt mit 3 Eigenschaften genannt werden h, sund l, aber ich werde andere geschickte Variationen annehmen, wie die HSL als ganzzahliges Empfangen (Verlust precision) und zur Ausgabe einer RGB - Ganzzahl.

Es kann davon ausgegangen werden, dass die Eingabe in Bereich und Format sicher ist. Sie können beide entscheiden. Ich empfehle dringend entweder die Bereiche 0-1 0-1 0-1oder 0-360 0-100 0-100für hsl und 0-1 0-1 0-1oder 0-255 0-255 0-255für rgb.

In jeder Antwort müssen beide oben genannten Punkte angegeben werden. Wenn Sie besonders stolz auf sie sind, können Sie Ihre Antworten mit verschiedenen Variationen versehen, auch wenn sie nicht weniger Zeichen enthalten als Ihre anderen Variationen. Legen Sie die kleinste auf.

Pseudo-Testfälle für 0-360 0-100 0-1000-255 0-255 0-255

h   s   l   → r   g   b

0   0   0   → 0   0   0
90  56  17  → 43  68  19
202 19  39  → 81  104 118
72  55  26  → 88  103 30

Die Formeln zur Umrechnung finden Sie hier :

Dies ist eine gute Möglichkeit, die Konvertierung zu visualisieren:


Ihr vorgeschlagene Bereich für Hvon 0-360ist [0,360), wäre es als besser geschrieben werden 0-359?
Jonathan Allan

3
@ JonathanAllan Ich denke, es könnte etwas verwirrender aussehen, was für mich nahe legt, dass 395.1 keine mögliche Eingabe ist. Wenn überhaupt, ist die Verwendung der a-bNotation an sich falsch, wenn es sich um nicht ganzzahlige Werte handelt, aber ich würde sagen, dass es in Ordnung ist, die Frage besser lesbar zu halten. Wenn sich jemand beschwert, werde ich es überdenken.
Vielen

Ja, einig über den Punkt 359.1 - verwenden Sie vielleicht einfach die Standardnotation von [0,360)damals :)
Jonathan Allan

überrascht zu sehen, keine glsl Antworten;)
Towc

Antworten:


8

JavaScript (ES6), 98 95 94 Byte

Nimmt H in [0,360) und S / L in [0,1) . Die Ausgänge R , G und B als Array von 3 floaten in [0,1] .

(H,S,L)=>[5,3,1].map(i=>A(L*2)*S*([1,Y,0,0,Y,1][(i-~H)%6]-.5)+L,Y=(A=n=>n>1?2-n:n)((H/=60)%2))

Testfälle

Dieses Snippet konvertiert die Ergebnisse zurück in [0,255] .

Wie?

Initialisierungscode

Y = (                  // we compute Y = 1 - |(H/60) mod 2 - 1| = X / C
  A = n =>             // A = function that returns 1 - |n - 1|
    n > 1 ?            //   first compare n with 1
      2 - n            //     which allows to simplify the formula to either 2 - n
    :                  //   or
      n                //     just n
)((H /= 60) % 2)       // divide H by 60 and compute Y = A(H % 2)

Haupt code

[5, 3, 1].map(i =>     // for each i in (5, 3, 1):
  A(L * 2) * S * (     //   compute (1 - |2L - 1|) * S (this is C), and multiply it by:
    [1, Y, 0, 0, Y, 1] //     either 0, 1 or Y (let's call this factor K), picked from
    [(i - ~H) % 6]     //     a cyclic sequence of period 6, using i and ~H (-6 ≤ ~H ≤ -1)
    - .5               //     minus 1/2
  )                    //   this gives: C(K - 1/2) = CK - C/2, where CK = 0, C or X
  + L                  //   we add L, leading to CK - C/2 + L = CK + m
)                      // end of map() --> returns [R, G, B]

Permutationen von (0, C, X)

Der etwas knifflige Teil besteht darin, die richtige Permutation von (0, C, X) entsprechend dem Winkel der Farbtonkomponente zu erzeugen . Wie in der folgenden Abbildung gezeigt, wird jeder Spaltenwert aus derselben Zyklussequenz von Periode 6 ausgewählt , beginnend mit unterschiedlichen Offsets. Im obigen Code verwenden wir - ~ H anstelle von nur + H, weil wir H zu einer ganzen Zahl zwingen müssen . Daher die Offsets (5,3,1) anstelle von (0,4,2) .

                       C,X,0,0,X,C,C,X,0,0,X,C, ...
 +------> C,X,0,0,X,C  <--------->                  offset = 0, (0 - 1) mod 6 = 5
 | +----> X,C,C,X,0,0          <--------->          offset = 4, (4 - 1) mod 6 = 3
 | | +--> 0,0,X,C,C,X      <--------->              offset = 2, (2 - 1) mod 6 = 1
 | | |
(C,X,0) for   0 ≤ H <  60
(X,C,0) for  60 ≤ H < 120
(0,C,X) for 120 ≤ H < 180
(0,X,C) for 180 ≤ H < 240
(X,0,C) for 240 ≤ H < 300
(C,0,X) for 300 ≤ H < 360

Würde nehmen Hin [0,6)und bei der Ausgabe [0,1]speichern einige Bytes?
Jonathan Allan

@ JonathanAllan Ah, ich habe nicht bemerkt, dass das E / A-Format locker ist. Vielen Dank!
Arnauld

4

Mathematica, 155 Bytes

(x~Clear~c;d=Piecewise@Table[{(P=Permutations)[P@{c,x,0}][[42,i]],(i-1)<=#<i*p},{i,6}];c=(1-Abs[2#3-1])#2;x=c(1-Abs[Mod[#/(p=60),2]-1]);m=#3-c/2;(m+d)255)&


Probieren Sie es online!



1
@totallyhuman Ich halte das nicht für richtig, da HueHSB (AKA HSV) nicht HSL ist (siehe Abbildungen 2a und 2b auf der verlinkten Wikipedia-Seite).
Jonathan Allan

1
Jenny - wenn es richtig ist, gibt es keinen Grund, es nicht als Byteanzahl mit Ihrem nicht eingebauten unten zu posten!
Jonathan Allan

1
@ JonathanAllan Oh, so ist es. Es ist etwas ärgerlich, wie es RGBColorexistiert, HSLColoraber nicht. > _>
totalhuman

Gibt es eine ungolfed Version davon?
User76284

4

Python 2 , 32 Bytes

from colorsys import*;hls_to_rgb

Probieren Sie es online!

Diese Funktionalität ist tatsächlich über das hls_to_rgbInnere der colorsysBibliothek in Python integriert . Das Format für Mineneingaben ist ein HLS-Bereich von 0 bis 1 (anstelle von HSL sind beide gebräuchliche Akronyme für dasselbe Thema (obwohl HSL häufiger vorkommt)). Und meins gibt RGB-Werte in einem Tupel mit einem Bereich von 0 bis 1 aus.

Credits

Vielen Dank an Jonathan Allan, der darauf hingewiesen hat, dass ich es nur importieren muss (und mir dann dabei helfen kann, die Anzahl der Bytes weiter zu reduzieren).


Ich denke, das können nur 31 Bytes sein, from colorsys import hls_to_rgbda gibt uns eine Funktion, die wiederverwendet werden kann. Bearbeiten - machen Sie diese 21 als from colorsys import*.
Jonathan Allan

1
@ JonathanAllan Dank, aktualisiert.
Neil

Eigentlich wohl nur import colorsysfür 15!
Jonathan Allan

@ JonathanAllan Nice, erneut aktualisiert.
Neil

1
so wahr es auch sein mag, ich denke, das beeinflusst den Geist des Codegolfspiels ein bisschen zu sehr: /
Towc

4

C ++, 228 221 Bytes

-7 Bytes dank Zacharý

#define S(o,n)r[t[int(h[0])/60*3+o]+o-2]=(n+h[2]-c/2)*255;
void C(float*h,int*r){float g=2*h[2]-1,c=(g<0?1+g:1-g)*h[1],a=int(h[0])%120/60.f-1;int t[]={2,2,2,3,1,2,3,3,0,4,2,0,4,1,1,2,3,1};S(0,c)S(1,c*(a<0?1+a:1-a))S(2,0)}

Die Argumente sind beide Arrays mit einer Mindestgröße von 3 Elementen (dh float hsl[3]undint rgb[3]

Okay. Nun, wie funktioniert das? Was ist das für eine lange Reihe?

Nun, es ist kein langes Array, es ist ein intArray. Abgesehen von Scherzen zeigt das Array an, um wie viele Positionen wir CX und 0 nach rechts verschieben, wenn wir die richtige Permutation auswählen möchten. + 2. Erinnern Sie sich, wie R ', G' und B 'ausgewählt sind?

Wie R ', G' und B 'ausgewählt werden

Nehmen wir an, wir haben eine "normale" Reihenfolge, die {C, X, 0} ist.

Wenn Sie nun die erste Permutation (dh {C, X, 0}) auswählen, müssen Sie nicht verschieben. Dies entspricht genau der Verschiebung um 0 nach rechts. Die ersten drei Elemente des Arrays sind also 0,0 und 0

Für die zweite Permutation ({X, C, 0}) müssen wir C um 1 nach rechts und X um -1 nach links verschieben, sodass das vierte, fünfte und sechste Element des Arrays 1, -1 und 0 ist

Und so weiter...

Bei der 3. und 4. Permutation muss ich die 0 um 2 nach links verschieben, also die Rechtsverschiebung um -2. Da es mehr als 2 negative Zahlen gibt, addiere ich eher 2 zu jedem Element im Array und subtrahiere 2 zur Laufzeit (aus Golfgründen, um nur ganze Zahlen im Array zu haben).



4

Python 2 , 119 112 Bytes

def f(h,s,l):c=(1-abs(2*l-1))*s;m=l-c/2;x=c*(1-abs(h%2-1))+m;c+=m;return[c,m,x,c,m,x,m,c,x,m][7-int(h)*5%9:][:3]

Probieren Sie es online!

Übernimmt die Eingabe als H=[0,6[, S=[0,1], L=[0,1]


3

HTML + JavaScript (ES6), 8 + 88 = 96 Byte

f=
(h,s,l)=>(p.style.color=`hsl(${h},${s}%,${l}%)`,getComputedStyle(p).color.match(/\d+/g))
<div oninput=o.textContent=f(h.value,s.value,l.value)>H: <input type=number min=0 max=360 value=0 id=h>°<br>S: <input type=number min=0 max=100 value=0 id=s>%<br>L: <input type=number min=0 max=100 value=0 id=l>%<pre id=o>0,0,0</pre>
<p id=p>

Nimmt die Eingabe als Winkel und zwei Prozent. Ich bewerte das HTML-Snippet <p id=p>und die JavaScript-Pfeilfunktion. Ich weiß nicht, welche Rundungsbrowser verwendet werden, daher können meine Antworten geringfügig von Ihren abweichen.


2

Schnelle 4, 218 Bytes

Akzeptiert HSL-Werte im Bereich [0,1] als Argumente und gibt ein Array zurück, das die RGB-Werte im gleichen Bereich enthält:

import Cocoa;typealias F=CGFloat;func f(h:F,s:F,l:F)->[F]{var r=F(),g=F(),b=F(),x=s*min(1-l,l),n=2*x/max(l+x,1e-9);NSColor(hue:h,saturation:n,brightness:l+x,alpha:1).getRed(&r,green:&g,blue:&b,alpha:nil);return[r,g,b]}

Die Idee ist, zuerst die Eingabe von HSL in HSB zu konvertieren und dann den HSB-Konstruktor des integrierten Farbobjekts in Cocoa zu verwenden, um die RGB-Werte abzurufen.

Die UIKit-Version hat genau die gleiche Länge, da die einzigen Ersetzungen sind:

  • CocoaUIKit
  • NSColorUIColor

Ungolfed:

#if os(iOS)
    import UIKit
    typealias Color = UIColor
#elseif os(OSX)
    import Cocoa
    typealias Color = NSColor
#endif

typealias F = CGFloat

func f(h: F,s: F,l: F) -> [F] {
    var r = F(), g = F(), b = F()

    let x = s * min(1 - l, l)
    let n = 2 * x / max(l + x, 1e-9)

    let color = Color(hue: h, saturation: n, brightness: l + x, alpha: 1)
    color.getRed(&r, green: &g,blue: &b, alpha: nil)

    return [r, g, b]
}

Der folgende Ausschnitt kann zum Testen verwendet werden, indem nur die Werte zu ersetzen h, sund l:

let h: CGFloat = 0
let s: CGFloat = 0
let l: CGFloat = 0

let result = f(h: h/360, s: s/100, l: l/100).map { Int(round($0*255)) }
print(result)

Leider kann ich keinen Link zu einer Online-Sandbox bereitstellen, da alle unter Linux laufen, das Cocoa nicht enthält.


2

GLSL (GL_ES) 160 144 134 131 Bytes

Der Farbton liegt im Bereich von
0 bis 6 (spart 3 Byte). Sat, Light und RGB sind 0 bis 1

vec3 f(vec3 c){return mix(c.bbb,mix(clamp(vec3(-1,2,2)-abs(c.r-vec3(3,2,4))*vec3(-1,1,1),0.,1.),vec3(c.b>.5),abs(.5-c.b)*2.),c.g);}

Probieren Sie es auf Buch der Shader

Verwendete das Colorpicker-Tool auf einem Druckbildschirm, um die korrekte Ausgabe zu testen, mit
Ausnahme eines kleinen Fehlers auf 202 19 39 → 81 104 118, der 80 104 118 ergab


1

R 88 Bytes

function(h,s,l){v=(2*l+s*(1-abs(2*l-1)))/2;col2rgb(hsv(h,ifelse(v==0,v,(2*(v-l))/v),v))}

Probieren Sie es online!

Diese Funktion nimmt als Eingabe die H-, S- und L-Werte als 0-1-Bereichswerte und gibt die RGB-Werte als 0-255-Bereichswerte aus. Es konvertiert die HSL-Darstellung in eine HSV-Darstellung, hsv()konvertiert dann die HSV-Darstellung in eine R-Farbe (dh hexadezimale Darstellung - #rrggbb) und col2rgb()konvertiert dann die R-Farbe in RGB-Werte.


1

Jelly ,  39  32 Bytes

-1 dank caird coinheringaahing ( %2is just )
-1 und / oder inspiration für -4 dank caird coinheringaahing auch!

Ḥ;Ḃ’ACש"⁵×\;0+³_®H¤⁴Ḟị336Œ?¤¤œ?

Ein vollständiges Programm mit drei Befehlszeilenargumenten:

  • L, H, SIn den Bereichen [0,1), [0,6)und [0,1)jeweils

Dies druckt eine Liste mit dem RGB-Format

  • [R, G, B] mit jedem der drei Werte im Bereich [0,1]

Hinweis: HKann auch wie gewünscht gewickelt werden [0,360).

Probieren Sie es online!

Wie?

Ḥ;Ḃ’ACש"⁵×\;0+³_®H¤⁴Ḟị336Œ?¤¤œ? - Main link: number, L (in [0,1]); number, H (in [0,6))
Ḥ                                - double                 =     2L
  Ḃ                              - modulo by 2            =              H%2
 ;                               - concatenate            = [   2L   ,   H%2]

   ’                             - decrement              = [   2L-1 ,   H%2-1]
    A                            - absolute               = [  |2L-1|,  |H%2-1|]
     C                           - complement             = [1-|2L-1|,1-|H%2-1|]
                                 -                        = [C/S     ,C/X]
         ⁵                       - 3rd program argument   = S  (in [0,1])
        "                        - zip with:
      ×                          -   multiplication       = [C,C/X]
       ©                         -   (copy the result, C, to the register)
           \                     - cumulative reduce with:
          ×                      -   multiplication       = [C, C/X*C] = [C,X]
            ;0                   - concatenate zero       = [C,X,0]
               ³                 - 1st program argument   = L
              +                  - add (vectorises)       = [C+L,X+L,L]
                   ¤             - nilad followed by link(s) as a nilad:
                 ®               -   recall from register = C
                  H              -   halve                = C/2
                _                - subtract               = [C+L-C/2,X+L-C/2,L-C/2]
                             ¤   - nilad followed by link(s) as a nilad:
                    ⁴            -   2nd program argument = H
                     Ḟ           -   floor                = floor(H)
                            ¤    -   nilad followed by link(s) as a nilad:
                       336       -     literal 336
                          Œ?     -     Shortest permutation of natural numbers with a
                                 -     lexicographical index of 336 in all permutations
                                 -     thereof            = [3,5,6,4,2,1]
                      ị          -   index into (1-indexed & modular)
                              œ? - get that permutation of [C+L-C/2,X+L-C/2,L-C/2]
                                 - implicit print

Ups, natürlich. Vielen Dank!
Jonathan Allan
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.