HSLからRGB値


17

RGB(赤緑青)カラーモデルの主な目的は、テレビやコンピューターなどの電子システムでの画像の検知、表現、および表示です。

HSL(Hue Saturation Lightness)は、1970年代にコンピューターグラフィックスの研究者によって設計された代替のカラーモデルであり、人間の視覚が色を作り出す属性を知覚する方法により密接に整合します。

RGBHSLの wiki記事は次のとおりです。グラフィックプログラムでは、HSLで計算を行い、後でほとんどの画面に適した形式(RGB)に変換するのが一般的です。

タスクは、HSLを入力として取り、RGBを出力する関数/プログラムを作成することです。

それらの間で一貫性がある限り、I / Oの好みの表現を選択できます。

例えば、それらは3つの要素を持つ配列/タプルまたは名前3つの特性を持つオブジェクトであることができるhsl、私は整数(失う精度)としてHSLを受信し、RGB整数を出力するように、他の巧妙な変化を受け入れるだろう。

入力は範囲と形式が安全であると見なすことができ、どちらも決定できます。範囲0-1 0-1 0-1または0-360 0-100 0-100hsl 0-1 0-1 0-1または0-255 0-255 0-255rgbのいずれかを強くお勧めします。

上記の両方を指定するために各回答が必要であり、他のバリエーションよりもキャラクターが少ない場合でも、特に誇りに思っている場合は、さまざまなバリエーションを回答に入れてください。一番小さいものを上に置きます。

0-360 0-100 0-100→の擬似テストケース0-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

変換の式はここにあります

これは、変換を視覚化する良い方法として:


Hofの推奨範囲0-360[0,360)、次のように記述した方がよいでしょう0-359か?
ジョナサンアラン

3
@JonathanAllan私にとっては、395.1は可能な入力ではないことを示唆しているように、少しわかりにくいかもしれません。どちらかa-bと言えば、整数以外の値を処理するときに表記法を使用すること自体が間違っていますが、質問をより読みやすくすることは問題ないと思います。誰にも文句を言うならば、私はので、そのアウトを指し示すためのおかげで、それを再考するだろう
towc

ええ、359.1の点で合意しました-たぶん[0,360)当時の標準表記を使用してください:)
ジョナサンアラン

glslの回答がないことに驚いた;)
towc

回答:


8

JavaScript(ES6)、98 95 94バイト

かかるHの0360 [)およびS / Lにおける[0,1) [0,1)に3つのfloatの配列としてRG、およびBを出力します。

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

テストケース

このスニペットは結果を[0,255]に変換します。

どうやって?

初期化コード

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を整数に。したがって、オフセットは(0,4,2)ではなく(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

取り込んH[0,6)出力すると[0,1]、いくつかのバイトが節約されますか?
ジョナサンアラン

@JonathanAllanああ、I / Oフォーマットがゆるいことに気付かなかった。ありがとう!
アーナルド

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
@totallyhuman HueHSBではなくHSB(別名HSV)もそうだとは思いません(リンクされているウィキペディアのページの図2aおよび2bを参照)。
ジョナサンアラン

1
ジェニー-それが正しければ、以下の非組み込みでバイト数としてそれを投稿しない理由はありません!
ジョナサンアラン

1
@ジョナサンアランああ、そうです。RGBColor存在するのは少し面倒ですが、ありHSLColorません。> _>
完全に人間の

これの無料版はありますか?
user76284

4

Python 2、32バイト

from colorsys import*;hls_to_rgb

オンラインでお試しください!

この機能は、実際hls_to_rgbにはcolorsysライブラリの内部を介してPythonに組み込まれています。鉱山の入力形式は、0-1のHLSの範囲です(HSLの代わりに、両方とも同じことの一般的な頭字語です(ただし、HSLがより一般的です))。そして、私は0から1までの範囲のタプルでRGB値を出力します。

クレジット

Jonathan Allanに、それをインポートするだけでよいことを指摘してくれました(そして、さらにバイトカウントの削減に役立ちました)。


from colorsys import hls_to_rgb再利用可能な関数を提供するため、これは31バイトにしかならないと思います。編集-その21をとして作成しfrom colorsys import*ます。
ジョナサンアラン

1
@JonathanAllanありがとう、更新しました。
ニール

実はたぶんたっimport colorsysたの15分!
ジョナサンアラン

@JonathanAllan Nice、再び更新されました。
ニール

1
しかし、それは本当かもしれませんが、これはコードゴルフの精神に少し影響を与えすぎると思います:/
towc

4

C ++、228 221バイト

ザカリーのおかげで-7バイト

#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

2番目の順列({X、C、0})では、Cを1だけ右にシフトし、Xを-1だけ左にシフトする必要があるため、配列の4番目、5番目、6番目の要素は1、-1、0です。

等々...

3番目と4番目の順列の場合、0を2だけ左にシフトする必要があるため、-2だけ右にシフトします。負の数が2つ以上あるため、実行時に配列の各要素に2を加算し、2を減算します(ゴルフの理由により、配列に整数のみを含める)。




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>

入力を角度と2つのパーセンテージとして受け取ります。HTMLスニペット<p id=p>とJavaScriptの矢印関数を採点しています。丸めブラウザが何を使用するのかわかりませんので、私の答えはあなたのものとは少し異なるかもしれません。


2

Swift 4、218バイト

範囲[0,1]のHSL値を引数として受け入れ、同じ範囲の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に変換し、次にCocoaの組み込みカラーオブジェクトのHSBコンストラクターを使用してRGB値を取得することです。

UIKitバージョンの長さはまったく同じです。代替品は次のとおりです。

  • CocoaUIKit
  • NSColorUIColor

ゴルフをしていない:

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

次のコードは、単にの値を置き換えることにより、試験のために使用することができhsおよび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)

残念なことに、それらはすべてCocoaを含まないLinux上で実行されるため、オンラインサンドボックスへのリンクを提供できません。


2

GLSL(GL_ES) 160 144 134 131バイト

色相の範囲は0〜6(3バイトを保存)、
Sat、light、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);}

シェーダーの本で試してみてください

印刷画面でカラーピッカーツールを使用して、正しい出力をテストしました。
ただし、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の範囲の値として受け取り、RGB値を0〜255の範囲の値として出力します。HSL表現をHSV表現hsv()に変換し、HSV表現をR色に変換するために使用します(16進表現-#rrggbb)。次にcol2rgb()、R色をRGB値に変換するために使用します。


1

ゼリー 39  32 バイト

-1 caird coinheringaahingのおかげ(%2ちょうど
-1および/または-4のインスピレーションもcaird coinheringaahingのおかげです!

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

3つのコマンドライン引数を取る完全なプログラム:

  • LHSの範囲で[0,1)[0,6)及び[0,1)それぞれ

RGB形式のリストを出力します

  • [R, G, B] 範囲内の3つの値のそれぞれ [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

おっと、もちろん。ありがとう!
ジョナサンアラン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.