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 이하이면 어두워지는 것을 알았습니다. 이것은 적절한 방법이 아닐 수도 있지만 하나입니다.
Rick Kuipers 2012 년

1
이미 tinyColor를 사용하고 있으므로 색상을 HSL로 변환 하고 L 구성 요소를 살펴보십시오 . 1 = 흰색, 0 = 검은 색
Andreas

4
@Andreas HSL 가벼움은 인간의 인식을 고려하지 않습니다. L 값이 0.5이면 색조에 따라인지되는 밝기가 달라집니다.
Alnitak

1
@Alnitak 당신 말이 맞지만 TO에 대한 설명은 정확하지 않습니다. 따라서 3/8 미만의 값은 그의 목적에 맞게 충분히 어두울 수 있습니다.
Andreas

1
@Andreas 그에 따라-내 대답에서 ITU 휘도 값을 보면 파란색이 녹색보다 1/10로 밝다는 것을 알 수 있습니다.
Alnitak 2012-08-20

답변:


226

세 가지 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
}

편집하다

5 월 2014 년부터 tinycolor지금이 getBrightness()대신 위의 ITU-R 것들의 요소에 가중치를 CCIR601를 사용하여 불구하고 기능을,.

편집하다

결과 루마 값 범위는 0..255입니다. 여기서 0은 가장 어둡고 255는 가장 밝습니다. 128보다 큰 값은에서 밝은 것으로 간주됩니다 tinycolor. (@ pau.moreno 및 @Alnitak의 댓글에서 뻔뻔스럽게 복사 됨)


11
한동안 자바 스크립트에서 좋은 비트 조작을 보지 못했습니다. 멋진 것. en.wikipedia.org/wiki/Rec._709#Luma_coefficients
jbabey

2
좋은 코드이지만 테스트 후 var luma = (r + g + b) / 3; if (luma <128) {// 더 유용합니다. }
테리 린

2
@TerryLin 왜? 주어진 계수는 녹색이 빨간색 (그리고 파란색)보다 더 밝게 인식 된다는 사실을 허용 하는 표준 ITU 값입니다 .
Alnitak

1
결과 luma값 범위는입니다 0..255. 여기서는 0가장 어둡고 가장 255밝습니다 (세 계수의 합은 1).
pau.moreno 2015-08-26

1
단지 2014년 5월 이후 @gabssnake 및 isDark()임계 값은 하드 코드 (128)에있다
알니 타크

21

TinyColor의 라이브러리는 (당신이 이미 언급 한) 검사와 그들 사이에 색상을 조작하기위한 여러 가지 기능을 제공합니다 :

  • getBrightness

    Web Content Accessibility Guidelines (버전 1.0)에 정의 된대로 0-255 범위에서 색상의인지 된 밝기를 반환합니다 .

    tinycolor("#fff").getBrightness(); // 255
  • isLight

    색상의 감지 된 밝기가 밝은 지 여부를 나타내는 부울을 반환합니다.

    tinycolor("#fff").isLight(); // true
    tinycolor("#000").isLight(); // false
  • isDark

    색상의 감지 된 밝기가 어두운 지 여부를 나타내는 부울을 반환합니다.

    tinycolor("#fff").isDark(); // false
    tinycolor("#000").isDark(); // true
  • getLuminance

    Web Content Accessibility Guidelines (버전 2.0)에 정의 된대로 0-1에서 색상의인지 된 광도를 반환합니다 .

    tinycolor("#fff").getLuminance(); // 1

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! 나는 감지 : 그들 모두와 함께 정확했다, 여러 가지 색상으로 테스트
데이비드 달 BUSCO

colorIsDarkOrLight (color) {var hex = color.replace ( "#", ""); var c_r, c_g, c_b, 밝기 = ""; 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); } return 밝기> 155; },
Pedro Henrique 19

16 진수 3 문자 및 6과 함께 사용
Pedro Henrique 2019

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. 세 가지 모두의 평균을 취하십시오.
  4. 다른 사람들이 여기에서 제안한 가중 평균을 사용하십시오.

AFAIK 는 Wikipedia 페이지에 설명 된 루마 계산 만 인식 기반 모델입니다.
Alnitak

2
물리적 인 빛 에너지와 지각 된 밝기의 차이를 지적하는 것은 좋지만, 나는 당신이 다소 혼란 스럽다고 생각합니다. 링크 한 Wikipedia 기사의 섹션에는 네 번째 글 머리 기호가 있습니다. " 지각 적으로 관련된 대안은 밝기 차원으로 luma, Y '를 사용하는 것입니다."(강조 내)에 나와있는 수식을 Alnitak의 그리고 로빈의 대답. 즉, 당신이 생략하고 권장하는 방법은 인간의 인식과 가장 잘 어울리는 방법입니다.
John Y

@JohnY 예, 그것이 내가 말하려고했던 것입니다-그는 나머지 답변과 실제로 일치하는 유일한 사람을 제외했습니다.
Alnitak

네, 여기서 혼란스러워하는 사람은 나뿐이었습니다. 나는 그것에 대해 괜찮습니다 :) 나는 단지 에너지와 지각 사이에 차이가 있다는 주요 요점을 얻고 싶었습니다. 그에 따라 답변을 업데이트하겠습니다.
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);

당신은 전체 16 진수 값 (# 000000 및 #FFFFFF)를 사용할 필요가 있기 때문에 그의를 @Vivek
TheCrazyProfessor

2

가능한 해결책은 색상 을 RGB에서 HSB 로 변환하는 것 입니다. HSB는 색조, 채도 및 밝기를 나타냅니다 (HSV라고도하며 여기서 V는 값임). 그런 다음 확인할 매개 변수는 밝기입니다.


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.