16進数の色が「黒すぎる」かどうかを確認するにはどうすればよいですか?


111

カラーピッカーで選択した色の濃さを評価して、「黒すぎる」かどうかを確認し、そうである場合は白に設定します。16進数値の最初の文字を使用してこれを取り除くことができると思いました。動作していますが、一部の正当な「明るい」色も切り替えています。

私はこれを行うコードを持っています:

        if (lightcolor.substring(0,3) == "#00"|| lightcolor.substring(0,3) == "#010"){
            lightcolor="#FFFFFF";
            color=lightcolor;
        }

色が特定のレベルの暗さを超えたことを知るには、16進数演算を使用したより効率的な方法が必要ですか?lightcolor + "some hex value" <= "some hex value"のように、それを白に設定します。

tinyColorを追加しましたが、これは役に立つかもしれませんが、確かではありません。


1
カラーピッカーを立ち上げて値を確認してみましたか?R、G、Bがすべて70未満になると暗くなることに気づきました。これは適切な方法ではないかもしれませんが、それは1つの方法です。
リックカイパーズ

1
tinyColorを既に使用しているので、色をHSLに変換し、Lコンポーネントを確認します。1 =白、0 =黒
Andreas

4
@Andreas HSL明度は人間の知覚を考慮に入れていません。L値が0.5の場合、色相ごとに異なる知覚される明るさになります。
Alnitak 2012

1
@Alnitakその通りですが、TOの説明は正確ではありません。したがって、3/8未満の値は、彼の目的には十分暗い可能性があります。
Andreas

1
@Andreas依存します-私の回答でITU輝度値を見ると、青は緑の1/10の明るさとして知覚されることがわかります。
Alnitak 2012

回答:


226

3つのRGBコンポーネントを個別に抽出し、標準の数式を使用して、結果のRGB値を知覚される明るさに変換する必要があります。

6文字の色を仮定します。

var c = c.substring(1);      // strip #
var rgb = parseInt(c, 16);   // convert rrggbb to decimal
var r = (rgb >> 16) & 0xff;  // extract red
var g = (rgb >>  8) & 0xff;  // extract green
var b = (rgb >>  0) & 0xff;  // extract blue

var luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709

if (luma < 40) {
    // pick a different colour
}

編集

2014年5月以降、上記のITU-R係数の代わりにCCIR601重み係数を使用しtinycolorていgetBrightness()ますが、関数が追加されました。

編集

結果の輝度値の範囲は0〜255です。0が最も暗く、255が最も明るくなります。128より大きい値は、によって明るいと見なされtinycolorます。(@ pau.morenoと@Alnitakのコメントから恥知らずにコピーされました)


11
しばらくの間、JavaScriptでの適切なビット操作を見ていません。クール。en.wikipedia.org/wiki/Rec._709#Luma_coefficients
jbabey

2
良いコードですが、テスト後はvar luma =(r + g + b)/ 3;をお勧めします。if(luma <128){//より便利になります。}
Terry Lin

2
@TerryLinなんで?与えられた係数は、緑が赤(そして青)よりも明るく知覚されるという事実を可能にする標準 ITU値です。
アルニタク2015

1
結果のluma値の範囲はです0..255。ここ0で、は最も暗く、最も明るくなり255ます(3つの係数の合計が1になります)。
pau.moreno 2015

1
@gabssnakeは2014年5月以降のみで、isDark()しきい値は128にハードコードされています
Alnitak

21

TinyColorのライブラリは、(あなたはすでにそれを言及した)検査し、それらの間で、色を操作するためのいくつかの機能を提供します。


15

このWooCommerce Wordpress PHP関数(wc_hex_is_light)を見つけ、JavaScriptに変換しました。正常に動作します!

function wc_hex_is_light(color) {
    const hex = color.replace('#', '');
    const c_r = parseInt(hex.substr(0, 2), 16);
    const c_g = parseInt(hex.substr(2, 2), 16);
    const c_b = parseInt(hex.substr(4, 2), 16);
    const brightness = ((c_r * 299) + (c_g * 587) + (c_b * 114)) / 1000;
    return brightness > 155;
}

1
超クール、THX!私はそれをいくつかの色でテストしました、検出はそれらすべてで正しかったです:)
David Dal Busco

colorIsDarkOrLight(color){var hex = color.replace( "#"、 ""); var c_r、c_g、c_b、brightness = ""; if(hex.length == 3){c_r = parseInt(hex.substr(0、2)、16); c_g = parseInt(hex.substr(1、2)、16); c_b = parseInt(hex.substr(2、2)、16); 明るさ=(c_r * 299 + c_g * 587 + c_b * 114)/ 1000; } else {c_r = parseInt(hex.substr(0、2)、16); c_g = parseInt(hex.substr(2、2)、16); c_b = parseInt(hex.substr(4、2)、16); }輝度> 155を返します。}、
ペドロエンリケ

16進数の3文字と6で使用
ペドロエンリケ

6

輝度を計算できます:

したがって、輝度は、表面がどの程度明るく見えるかを示すものです。

したがって、テキストを白にするか黒にするかを選択するのは素晴らしいことです。

var getRGB = function(b){
    var a;
    if(b&&b.constructor==Array&&b.length==3)return b;
    if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(b))return[parseInt(a[1]),parseInt(a[2]),parseInt(a[3])];
    if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(b))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];
    if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(b))return[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],
16)];
    if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(b))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];
    return (typeof (colors) != "undefined")?colors[jQuery.trim(b).toLowerCase()]:null
};

var luminance_get = function(color) {
    var rgb = getRGB(color);
    if (!rgb) return null;
        return 0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2];
}

上記の方法では、さまざまな形式で色を渡すことができますが、アルゴリズムは基本的にはだけですluminance_get

使用したとき、輝度がより大きい場合は黒に、それ以外の場合180は白に設定していました。


5

ここで、輝度と明るさの間には重要な違いがあります。結局のところ、輝度は、特定の領域を移動するエネルギーの量の尺度であり、知覚システムがそのエネルギーをどのように認識するかを完全に無視しています。一方、明るさは、私たちがそのエネルギーをどのように知覚し、輝度と知覚システムとの関係を考慮に入れるかを示す尺度です。(混乱のポイントとして、相対輝度と呼ばれる用語があります。これは、明るさの用語と同義に使用されているようです。それは私をうまく動かしました)。

正確には、他の人が示唆しているように、「明るさ」、「値」、または「比較的輝度」を探しています。これは、いくつかの異なる方法で計算できます(人間を対象としています)。http://en.wikipedia.org/wiki/HSL_and_HSV#Lightness

  1. R、G、Bの最大値を取ります。
  2. R、G、Bから最大値と最小値の平均を取ります。
  3. 3つすべての平均を取ります。
  4. 他の人がここで提案しているように、いくつかの加重平均を使用します。

私の知る限り唯一のルマ Wikipediaのページに記載計算は、認知ベースのモデルです。
Alnitak 2012

2
物理的な光エネルギーと知覚される明るさの違いを指摘するのは良いことですが、私はあなたが物事をかなり混同していると思います。リンクしたWikipediaの記事のセクションには4番目の箇条書きがあり、「より知覚的に適切な代替策は、明度の次元としてルミナンスY 'を使用することです」(強調は私のものです)、次にアルニタクのそしてロビンの答え。言い換えると、あなたが除外して推奨していない方法は、人間の知覚に最もよく一致する方法です。
John Y

@JohnYはい、それは私が言おうとしていたことです-彼の答えの残りと実際に一致する唯一のものは除外されています。
アルニタク2012

はい、ここで混乱したのは私だけでした。私はそれで大丈夫です:)私は、エネルギーと知覚との間に違いがあるということ全体の主要なポイントを取得したかっただけです。それに応じて回答を更新します。
David Nguyen

4

これは16進数で動作します。例:#fefefe

function isTooDark(hexcolor){
    var r = parseInt(hexcolor.substr(1,2),16);
    var g = parseInt(hexcolor.substr(3,2),16);
    var b = parseInt(hexcolor.substr(4,2),16);
    var yiq = ((r*299)+(g*587)+(b*114))/1000;
    // Return new color if to dark, else return the original
    return (yiq < 40) ? '#2980b9' : hexcolor;
}

あなたは返すようにそれを変更することができますtrueまたはfalse変更によって

return (yiq < 40) ? '#2980b9' : hexcolor;

return (yiq < 40);

@Vivekこれは、完全な16進数値(#000000および#ffffff)を使用する必要があるためです
TheCrazyProfessor

2

可能な解決策は、RGBからHSBに色を変換することです。HSBは、色相、彩度、および明るさを表します(HSVとも呼ばれ、Vは値を表します)。次に、確認するパラメータは1つだけです。明るさです。


1

この会話は数年前のものだと思いますが、それでも関連性があります。私のチームがJava(SWT)でも同じ問題を抱えていて、これがもう少し正確であることがわかりました。

private Color getFontColor(RGB bgColor) {
    Color COLOR_BLACK = new Color(Display.getDefault(), 0, 0, 0);
    Color COLOR_WHITE = new Color(Display.getDefault(), 255, 255, 255);

    double luminance = Math.sqrt(0.241 
       * Math.pow(bgColor.red, 2) + 0.691 * Math.pow(bgColor.green, 2) +  0.068 
       * Math.pow(bgColor.blue, 2));
    if (luminance >= 130) {
        return COLOR_BLACK;
    } else {
        return COLOR_WHITE;
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.