HSL - RGB değerleri


17

RGB (Kırmızı Yeşil Mavi) renk modelinin temel amacı, televizyonlar ve bilgisayarlar gibi elektronik sistemlerde görüntülerin algılanması, temsil edilmesi ve görüntülenmesidir.

HSL (Hue Saturation Lightness), 1970'lerde bilgisayar grafikleri araştırmacıları tarafından, insan vizyonunun renk yapma özelliklerini algılama biçimiyle daha yakından uyumlu olması için tasarlanmış alternatif bir renk modelidir.

RGB ve HSL için wiki makaleleri . Grafik programlarının HSL'de hesaplamaları yapması ve daha sonra çoğu ekran için tercih edilen biçime dönüştürmesi yaygındır: RGB.

Görev, HSL'yi giriş olarak alan ve RGB çıkışı yapan bir işlev / program yazmaktır.

I / O için tercih ettiğiniz temsili, aralarında tutarlı olduğu sürece seçebilirsiniz.

Örneğin bunlar, 3 elemanları ile bir dizi / demet veya adlandırılan 3 özelliklere sahip bir nesne olabilir h, sve l, ancak bir tamsayı (kaybetme hassas) HSL alınması ve bir RGB tamsayı çıkış gibi diğer akıllı varyasyonlarını kabul edilmeyecektir.

Girişin, her ikisi de karar verebileceğiniz menzil ve formatta güvenli olduğu varsayılabilir. Ben kesinlikle aralıkları 0-1 0-1 0-1veya 0-360 0-100 0-100hsl ve 0-1 0-1 0-1veya 0-255 0-255 0-255rgb için öneririz .

Her bir cevabın yukarıdakilerin her ikisini de belirtmesi ve onlardan özellikle gurur duyuyorsanız, diğer varyasyonlarınızdan daha az karakterleri olmasa bile cevaplarınıza çeşitli varyasyonlar eklemeniz gerekir. En küçüğünü üstüne koy.

İçin sahte test vakaları 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

Dönüşüm formüllerini burada bulabilirsiniz :

Bu, dönüşümü görselleştirmenin güzel bir yolu olarak:


Sizin önerilen aralık Hiçinde 0-360olduğu [0,360), daha iyi olarak yazılabilir olur 0-359?
Jonathan Allan

3
@JonathanAllan Bana göre, 395.1'in olası bir girdi olmadığını düşündüren biraz daha kafa karıştırıcı görünebilir. Herhangi bir şey varsa, a-btamsayı olmayan değerlerle uğraşırken notasyonu kullanmak kendi başına yanlıştır, ancak soruyu daha okunabilir tutmanın iyi olduğunu söyleyebilirim. Başka biri şikayet ederse, yeniden
düşüneceğim

Evet, 359.1 noktasında anlaştılar - belki de [0,360)o zamanki standart gösterimi kullanın :)
Jonathan Allan

glsl

Yanıtlar:


8

JavaScript (ES6), 98 95 94 bayt

Alır H içinde 0,360 [) ve S / L olarak [0,1) . [0,1) ' de 3 dalgalı bir dizi olarak R , G ve B çıkışları .

(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))

Test senaryoları

Bu pasaj sonuçları tekrar [0,255] 'e dönüştürür .

Nasıl?

Başlatma kodu

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)

Ana kod

[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]

Permütasyonları (0, C, X)

Biraz zor olan kısım, renk tonu bileşeninin açısına göre (0, C, X) doğru permütasyonunu üretmektir . Aşağıdaki şekilde gösterildiği gibi, her sütun değeri, farklı ofsetlerden başlayarak , aynı dönem 6 döngü döngüsünden alınır . Yukarıdaki kodda, sadece + H yerine - ~ H kullanıyoruz çünkü H'yi bir tam sayıya zorlamamız gerekiyor . Dolayısıyla (0,4,2) yerine ofsetler (5,3,1) .

                       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

Misiniz alarak Hiçinde [0,6)ve çıkışı [0,1]bazı bayt tasarrufu?
Jonathan Allan

@JonathanAllan Ah, I / O formatının gevşek olduğunu fark etmedim. Teşekkürler!
Arnauld

4

Mathematica, 155 bayt

(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)&


Çevrimiçi deneyin!



1
@totallyhuman HueHSL değil, HSB (AKA HSV) gibi doğru olduğunu düşünmüyorum (bağlantılı Wikipedia sayfasındaki şekil 2a ve 2b'ye bakınız).
Jonathan Allan

1
Jenny - eğer doğru ise, aşağıda yerleşik olmayan ile bayt sayısı olarak göndermemeniz için hiçbir sebep yoktur!
Jonathan Allan

1
@JonathanAllan Oh, öyle. Nasıl RGBColorvar olduğu biraz can sıkıcı ama HSLColoryok. > _>
totallyhuman

Bunun ungolfed versiyonu var mı?
user76284

4

Python 2 , 32 bayt

from colorsys import*;hls_to_rgb

Çevrimiçi deneyin!

Bu işlevsellik aslında Python'a kitaplığın hls_to_rgbiçinden yerleştirilmiştir colorsys. Biçim mayın girişleri 0-1 HLS aralığıdır (HSL yerine her ikisi de aynı şey için ortak kısaltmalardır [yine de HSL daha yaygındır]). Ve benimkisi RGB değerlerini 0 ile 1 arasında değişen bir demet halinde çıkarır.

Kredi

Jonathan Allan'a sadece içe aktarmam gerektiğini işaret ettiği için teşekkürler (ve daha sonra bayt sayısını azaltmama yardımcı oluyor).


Bence bu sadece 31 bayt olabilir from colorsys import hls_to_rgbçünkü bize tekrar kullanılabilecek bir fonksiyon veriyor. Düzenle - 21 olarak yap from colorsys import*.
Jonathan Allan

1
@JonathanAllan Teşekkürler, güncellendi.
Neil

Aslında sadece import colorsys15 yaşında !
Jonathan Allan

@JonathanAllan Nice, tekrar güncellendi.
Neil

1
ancak doğru olabilir, bence bu biraz fazla kodlama ruhunu etkiler: /
towc

4

C ++, 228 bayt

Zacharý sayesinde -7 bayt

#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)}

Argümanlar 3 elemanların asgari bir büyüklüğe sahip iki dizide (yani float hsl[3]veint rgb[3]

Tamam. Şimdi, bu nasıl çalışıyor? Bu uzun dizi nedir?

Uzun bir dizi değil, bir intdizi. Şaka bir yana, dizi doğru permütasyonu seçmek istediğimizde kaç pozisyon CX ve 0 sağa kaydırdığımızı gösterir, + 2. R ', G' ve B 'nin nasıl seçildiğini hatırlıyor musunuz?

R ', G' ve B 'nasıl seçilir?

Diyelim ki {C, X, 0} olan "normal" bir siparişimiz var

Şimdi, ilk permütasyon (yani {C, X, 0}) seçildiğinde, kaydırmamanız gerekir, bu da 0 ile sağa kaydırma ile tam olarak aynı şeydir. Yani dizinin ilk 3 elemanı 0,0 ve 0

İkinci permütasyon için ({X, C, 0}), C'yi 1'e ve sola X'i -1'e kaydırmalıyız, böylece dizinin dördüncü, beşinci ve altıncı öğesi 1, -1 ve 0'dır.

Ve bunun gibi...

3. ve 4. permütasyon durumunda, 0'ı 2'ye sola kaydırmam gerekiyor, bu yüzden sağa kaydırın -2. Negatif olan 2'den fazla sayı olduğundan, dizideki her öğeye 2 ve çalışma zamanında substract 2'yi ekliyorum (golf nedeniyle, dizide sadece tam sayılara sahip olmak için).



4

Python 2 , 119112 bayt

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]

Çevrimiçi deneyin!

Girdiyi şu şekilde alır H=[0,6[, S=[0,1], L=[0,1]


3

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

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>

Bir açı ve iki yüzde olarak girdi alır. HTML snippet'ini <p id=p>ve JavaScript ok işlevini puanlıyorum. Yuvarlanan tarayıcıların ne kullandığını bilmiyorum, bu yüzden cevaplarım sizinkinden biraz farklı olabilir.


2

Swift 4, 218 bayt

[0,1] aralığındaki HSL değerlerini bağımsız değişken olarak kabul eder ve aynı aralıktaki RGB değerlerini içeren bir dizi döndürür:

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]}

Fikir, ilk önce girişi HSL'den HSB'ye dönüştürmek, ardından RGB değerlerini almak için Cocoa'daki yerleşik renk nesnesinin HSB yapıcısını kullanmaktır.

UIKit sürümü, sadece değiştirmelerle aynı uzunluktadır:

  • 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]
}

Aşağıdaki kod sadece değerlerini değiştirerek, test etmek için de kullanılabilir h, sve 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)

Ne yazık ki, çevrimiçi bir sanal alana bağlantı sağlayamıyorum, çünkü hepsi Cocoa içermeyen Linux'ta çalışıyor.


2

GLSL (GL_ES) 160144134 131 bayt

Ton 0-6 aralığındadır (3 bayt kaydeder)
Cts, ışık ve rgb 0-1'dir

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);}

Gölgelendiriciler kitabında deneyin


202 19 39 → 81 104 118'de küçük bir hata haricinde , çıktıyı test etmek için baskı ekranında renk seçici aracı 80 80 118 verdi


1

R , 88 bayt

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))}

Çevrimiçi deneyin!

Bu işlev H, S ve L değerlerini 0-1 aralıklı değerler olarak alır ve RGB değerlerini 0-255 aralıklı değerler olarak verir. HSL gösterimini bir HSV temsiline hsv()dönüştürür , daha sonra HSV gösterimini bir R rengine dönüştürmek için kullanır (yani onaltılık gösterimi - #rrggbb), sonra col2rgb()R rengini RGB değerlerine dönüştürmek için kullanır .


1

Jöle ,  39  32 bayt

Caird coinheringaahing sayesinde -1 ( %2sadece )
-1 ve / veya -4 sayesinde ilham caird coinheringaahing !

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

Üç komut satırı argümanı alan tam bir program:

  • L, H, SAralıklarda [0,1),[0,6) ve [0,1)sırasıyla

RGB biçimini veren bir liste yazdırır.

  • [R, G, B] aralıktaki üç değerin her biri ile [0,1]

Not: HAynı şekilde sarılabilir [0,360).

Çevrimiçi deneyin!

Nasıl?

Ḥ;Ḃ’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

Hata! Teşekkürler!
Jonathan Allan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.