ค่า HSL เป็น RGB


17

วัตถุประสงค์หลักของโมเดลสี RGB (แดงเขียวน้ำเงิน) สำหรับการตรวจจับการแสดงและการแสดงภาพในระบบอิเล็กทรอนิกส์เช่นโทรทัศน์และคอมพิวเตอร์

HSL (Hue Saturation Lightness) เป็นรูปแบบสีทางเลือกที่ออกแบบในปี 1970 โดยนักวิจัยคอมพิวเตอร์กราฟิกเพื่อให้สอดคล้องกับวิธีการมองเห็นของมนุษย์ในการรับรู้คุณลักษณะการทำสี

นี่คือบทความวิกิพีเดียสำหรับเป็นRGBและHSL เป็นเรื่องปกติที่โปรแกรมกราฟิกจะทำการคำนวณใน HSL และแปลงเป็นรูปแบบที่ต้องการสำหรับหน้าจอส่วนใหญ่: RGB

ภารกิจคือการเขียนฟังก์ชั่น / โปรแกรมที่ใช้ HSL เป็นอินพุตและเอาต์พุต RGB

คุณสามารถเลือกการแสดงที่คุณต้องการสำหรับ I / O ตราบใดที่มันยังสอดคล้องกัน

ตัวอย่างเช่นพวกเขาสามารถเป็นอาร์เรย์ / tuple มี 3 องค์ประกอบหรือวัตถุที่มี 3 คุณสมบัติการตั้งชื่อh, sและlแต่ฉันจะยอมรับการเปลี่ยนแปลงที่ฉลาดอื่น ๆ เช่นรับ HSL เป็นจำนวนเต็ม (แพ้ความแม่นยำ) และการแสดงผลเป็นจำนวนเต็ม RGB

อินพุตสามารถสันนิษฐานได้ว่าปลอดภัยในช่วงและรูปแบบซึ่งคุณสามารถเลือกได้ทั้งสองแบบ ฉันขอแนะนำช่วง0-1 0-1 0-1หรือ0-360 0-100 0-100สำหรับ hsl และ0-1 0-1 0-1หรือ0-255 0-255 0-255สำหรับ rgb

แต่ละคำตอบจะต้องระบุทั้งสองข้อข้างต้นและใส่คำตอบต่าง ๆ ในคำตอบของคุณหากคุณภาคภูมิใจเป็นพิเศษถึงแม้ว่าพวกเขาจะไม่มีตัวอักษรน้อยกว่าการเปลี่ยนแปลงอื่น ๆ ของคุณ วางที่เล็กที่สุดไว้ด้านบน

กรณีทดสอบหลอกสำหรับ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

สูตรสำหรับการแปลงสามารถพบได้ที่นี่ :

นี่เป็นวิธีที่ดีในการเห็นการแปลง:


ช่วงที่คุณแนะนำสำหรับHของ0-360คือ[0,360)มันจะดีกว่าเขียนเป็น0-359?
Jonathan Allan

3
@JanathanAllan ฉันคิดว่ามันอาจดูสับสนเล็กน้อยสำหรับฉันซึ่งแสดงให้เห็นว่า 395.1 ไม่ใช่อินพุตที่เป็นไปได้ หากมีสิ่งใดการใช้a-bสัญกรณ์นั้นผิดในตัวเองเมื่อต้องจัดการกับค่าที่ไม่ใช่จำนวนเต็ม แต่ฉันว่ามันโอเคที่จะทำให้คำถามอ่านง่ายขึ้น หากมีคนอื่นบ่นฉันจะต้องคิดใหม่ดังนั้นขอขอบคุณที่ชี้ให้เห็น
towc

ใช่เห็นด้วยกับจุด 359.1 - อาจใช้สัญกรณ์มาตรฐานใน[0,360)ตอนนั้น :)
Jonathan Allan

ประหลาดใจที่ไม่เห็นคำตอบที่ glsl;)
2560

คำตอบ:


8

JavaScript (ES6), 98 95 94 ไบต์

ใช้เวลาHใน[0360)และS / Lใน[0,1) เอาท์พุทR , GและBเป็นอาร์เรย์ 3 ลอยใน[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))

กรณีทดสอบ

ข้อมูลโค้ดนี้จะแปลงผลการกลับเข้ามาใน[0255]

อย่างไร?

รหัสเริ่มต้น

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)

รหัสหลัก

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

พีชคณิตของ (0, C, X)

ส่วนที่ยุ่งยากเล็กน้อยคือการสร้างการเปลี่ยนแปลงที่ถูกต้องของ(0, C, X)ตามมุมขององค์ประกอบสี ดังที่แสดงในรูปต่อไปนี้แต่ละค่าของคอลัมน์จะถูกเลือกจากลำดับการวนรอบเดียวกันของช่วงเวลา6เริ่มต้นที่ออฟเซ็ตต่างกัน ในโค้ดข้างต้นเราใช้- ~ Hแทนที่จะเป็นเพียง+ Hเพราะเราจำเป็นต้องบังคับให้Hเป็นจำนวนเต็ม ดังนั้นการชดเชย(5,3,1)แทน(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

หากว่าการHใน[0,6)และแสดงผลใน[0,1]บันทึกไบต์บางอย่าง?
Jonathan Allan

@JanathanAllan อ่าฉันไม่ได้สังเกตว่ารูปแบบ I / O หลวม ขอบคุณ!
Arnauld

4

Mathematica, 155 ไบต์

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


ลองออนไลน์!



1
@tallyallyhuman ฉันไม่คิดว่ามันถูกต้องเหมือนที่HueHSB (AKA HSV) ไม่ใช่ HSL (ดูรูปที่ 2a และ 2b ในหน้า Wikipedia ที่เชื่อมโยง)
Jonathan Allan

1
Jenny - ถ้ามันถูกต้องไม่มีเหตุผลที่จะไม่โพสต์มันเพราะจำนวนไบต์ที่ไม่ใช่ของคุณสร้างขึ้นในด้านล่าง!
Jonathan Allan

1
@JanathanAllan โอ้เป็นอย่างนั้น มันน่ารำคาญเล็กน้อยที่RGBColorมีอยู่ แต่HSLColorก็ไม่ได้ > _>
มนุษย์

มีเวอร์ชั่นที่น่ารังเกียจไหม?
user76284

4

Python 2 , 32 ไบต์

from colorsys import*;hls_to_rgb

ลองออนไลน์!

ฟังก์ชั่นนี้สร้างขึ้นจริงใน Python ผ่านทางhls_to_rgbด้านในของcolorsysห้องสมุด รูปแบบอินพุตอินพุตเป็นช่วง 0-1 ของ HLS (แทน HSL ทั้งสองเป็นตัวย่อทั่วไปสำหรับสิ่งเดียวกัน [แม้ว่าแม้ว่า HSL จะเป็นเรื่องธรรมดามากขึ้น]) และเอาท์พุทค่า RGB ใน tuple ด้วยช่วงตั้งแต่ 0 ถึง 1

เครดิต

ขอบคุณ Jonathan Allan ที่ชี้ให้เห็นว่าฉันแค่ต้องนำเข้ามัน (และจากนั้นช่วยฉันลดจำนวนไบต์)


ฉันคิดว่านี่เป็นเพียง 31 ไบต์from colorsys import hls_to_rgbเนื่องจากมีฟังก์ชันที่อาจถูกใช้ซ้ำ แก้ไข - ให้ที่ from colorsys import*21
Jonathan Allan

1
@JonathanAllan ขอบคุณอัปเดตแล้ว
Neil

จริง ๆ แล้วอาจแค่import colorsys15!
Jonathan Allan

@JonathanAllan Nice อัปเดตอีกครั้ง
Neil

1
อย่างไรก็ตามความจริงมันอาจเป็นไปได้ฉันคิดว่าสิ่งนี้ส่งผลกระทบต่อวิญญาณของ codegolfing มากเกินไป: /
towc

4

C ++, 228 221 ไบต์

-7 ไบต์ขอบคุณ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)}

อาร์กิวเมนต์เป็นทั้งสองอาร์เรย์ที่มีขนาดขั้นต่ำ 3 องค์ประกอบ (เช่นfloat hsl[3]และint rgb[3]

ตกลง. ทีนี้มันทำงานอย่างไร อาเรย์แบบยาวนั้นคืออะไร?

มันไม่ใช่อาร์เรย์ที่ยาว แต่เป็นintอาร์เรย์ ตลกกันแล้วอาร์เรย์จะระบุด้วยจำนวนตำแหน่งที่ถูกต้องในการเลื่อน CX และ 0 เมื่อเราต้องการเลือกการเรียงสับเปลี่ยนที่ถูกต้อง + 2 โปรดจำไว้ว่าเลือก R ', G' และ B 'อย่างไร

วิธีการเลือก R ', G' และ B '

สมมติว่าเรามีคำสั่ง "ปกติ" ที่ {C, X, 0}

ตอนนี้เมื่อมีการเลือกการเปลี่ยนแปลงครั้งแรก (เช่น {C, X, 0}) คุณไม่จำเป็นต้องเปลี่ยนซึ่งเป็นสิ่งเดียวกันกับการเลื่อนขวาด้วย 0 ดังนั้นองค์ประกอบ 3 ประการแรกของอาร์เรย์คือ 0,0 และ 0

สำหรับการเรียงสับเปลี่ยนครั้งที่สอง ({X, C, 0}) เราจำเป็นต้องเลื่อนกะ C ไป 1 และซ้ายกะ X ด้วย -1 ดังนั้นองค์ประกอบที่สี่ห้าและหกของอาร์เรย์คือ 1, -1 และ 0

และอื่น ๆ ...

ด้วยกรณีของการเปลี่ยนลำดับที่ 3 และ 4 ฉันจำเป็นต้องเลื่อน shift ไปทางซ้าย 0 ถึง 2 ดังนั้นการเลื่อนที่ถูกต้องโดย -2 เนื่องจากมีจำนวนมากกว่า 2 หมายเลขที่เป็นค่าลบฉันจึงเพิ่ม 2 องค์ประกอบแต่ละตัวในอาร์เรย์และ substract2 ที่รันไทม์ (สำหรับเหตุผลในการเล่นกอล์ฟเพื่อให้มีเฉพาะตัวเลขทั้งหมดในอาร์เรย์)


221 ไบต์: pastebin.com/C8WaSSpb
Zacharý


3

HTML + JavaScript (ES6), 8 + 88 = 96 ไบต์

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>

รับอินพุตเป็นมุมและสองเปอร์เซ็นต์ ฉันให้คะแนนโค้ด HTML <p id=p>และฟังก์ชั่นลูกศร JavaScript ฉันไม่รู้ว่าการปัดเศษเบราว์เซอร์ใดใช้ดังนั้นคำตอบของฉันอาจแตกต่างจากของคุณเล็กน้อย


2

Swift 4, 218 bytes

ยอมรับค่า HSL ในช่วง [0,1] เป็นอาร์กิวเมนต์และส่งกลับอาร์เรย์ที่มีค่า RGB ในช่วงเดียวกัน:

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

แนวคิดคือการแปลงอินพุตจาก HSL เป็น HSB ก่อนจากนั้นใช้ตัวสร้าง HSB ของวัตถุสีในตัวใน Cocoa เพื่อดึงค่า RGB

เวอร์ชั่น UIKit มีความยาวเท่ากันเนื่องจากมีการทดแทนเพียงอย่างเดียวคือ:

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

ตัวอย่างต่อไปนี้สามารถนำมาใช้สำหรับการทดสอบโดยเพียงแค่เปลี่ยนค่าของh, sและ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)

น่าเสียดายที่ฉันไม่สามารถให้ลิงก์ไปยัง Sandbox ออนไลน์ได้เนื่องจากทั้งหมดนั้นทำงานบน Linux ซึ่งไม่รวมถึง Cocoa


2

GLSL (GL_ES) 160 144 134 131 ไบต์

ฮิวอยู่ในช่วง 0-6 (บันทึก 3 ไบต์)
วันเสาร์, แสงและ rgb คือ 0-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);}

ลองในหนังสือของเฉดสี

ใช้เครื่องมือ colorpicker บนหน้าจอพิมพ์เพื่อทดสอบผลลัพธ์ที่ถูกต้อง
ยกเว้นข้อผิดพลาดเล็กน้อยที่ 202 19 39 → 81 104 118 ซึ่งให้ 80 104 118


1

R , 88 ไบต์

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

ลองออนไลน์!

ฟังก์ชั่นนี้ใช้เป็นอินพุต H, S และ L ค่าเป็น 0-1 ranged ค่าและส่งออกค่า RGB เป็น 0-255 ranged ค่า มันแปลงการแทนค่า HSL เป็นตัวแทน HSV จากนั้นใช้hsv()ในการแปลงการแทน HSV เป็นสี R (เช่นการแทนค่าฐานสิบหก - #rrggbb) จากนั้นใช้col2rgb()เพื่อแปลงสี R เป็นค่า RGB


1

เจลลี่ ,  39  32ไบต์

-1 ขอบคุณcaird coinheringaahing ( %2เป็นเพียง)
-1 และ / หรือแรงบันดาลใจสำหรับ -4 ขอบคุณcaird coinheringaahingด้วย!

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

โปรแกรมเต็มรูปแบบที่รับอาร์กิวเมนต์บรรทัดคำสั่งสามข้อ:

  • L, H, Sในช่วง[0,1), [0,6)และ[0,1)ตามลำดับ

ซึ่งพิมพ์รายการที่ให้รูปแบบ RGB เป็น

  • [R, G, B] ด้วยแต่ละค่าสามค่าในช่วง [0,1]

หมายเหตุ: Hอาจห่อเช่นเดียว[0,360)หากว่า

ลองออนไลน์!

อย่างไร?

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

อ๊ะแน่นอน ขอบคุณ!
Jonathan Allan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.