कैसे जांच करें कि क्या हेक्स रंग "बहुत काला" है?


111

मैं एक रंग बीनने वाले द्वारा चुने गए रंग के अंधेरे का मूल्यांकन करने की कोशिश कर रहा हूं कि क्या यह "बहुत काला" है, और यदि ऐसा है, तो इसे सफेद पर सेट करें। मैंने सोचा कि मैं इसे उतारने के लिए हेक्स मान के पहले पात्रों का उपयोग कर सकता हूं। यह काम कर रहा है, लेकिन यह कुछ वैध "हल्के" रंगों को भी स्विच कर रहा है।

मेरे पास ऐसा करने वाला कोड है:

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

हेक्स गणित के साथ एक अधिक कुशल तरीका होना चाहिए ताकि यह पता चल सके कि एक रंग अंधेरे के एक निश्चित स्तर से परे चला गया है? जैसे अगर lightcolor + "कुछ हेक्स मान" <= "कुछ हेक्स मान" तो इसे सफेद पर सेट करें।

मेरे पास नन्हा सा जोड़ा है, जो इसके लिए इस्तेमाल हो सकता है, लेकिन मुझे यकीन नहीं है।


1
क्या आपने एक रंग बीनने और मूल्यों की जांच करने की कोशिश की है? मैंने देखा कि जब R, G और B सभी ~ 70 से कम होते हैं तो अंधेरा हो जाता है। यह उचित तरीका नहीं हो सकता है, लेकिन यह एक है।
रिक कुइपर्स

1
जैसा कि आप पहले से ही LittleColor का उपयोग कर रहे हैं, रंग को HSL में रूपांतरित करें और L घटक पर एक नज़र डालें । 1 = सफेद, 0 = काला
एंड्रियास

4
@Andreas HSL लपट मानव धारणा को ध्यान में नहीं रखता है। 0.5 के एक L मान में अलग-अलग hues के लिए एक अलग कथित चमक होगी।
अलनीतक

1
@Alnitak तुम सही हो, लेकिन TO का वर्णन ठीक नहीं है। तो 3/8 के नीचे का कोई भी मूल्य उसके उद्देश्य के लिए पर्याप्त अंधेरा हो सकता था।
एंड्रियास

1
@Andreas जो निर्भर करता है - यदि आप मेरे जवाब में ITU luminance मानों को देखते हैं, तो आप देखेंगे कि नीले रंग को केवल 1/10 के रूप में माना जाता है, जैसा कि हरा।
अलनीतक

जवाबों:


226

आपको व्यक्तिगत रूप से तीन आरजीबी घटकों को निकालना होगा, और फिर परिणामी RGB मानों को उनकी कथित चमक में बदलने के लिए एक मानक सूत्र का उपयोग करना होगा।

एक छह वर्ण रंग मानते हुए:

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 के बाद से tinycolorअब एक getBrightness()फ़ंक्शन है, ऊपर ITU-R वाले के बजाय CCIR601 भारित कारकों का उपयोग करते हुए।

संपादित करें

परिणामी लूमा मान सीमा 0..255 है, जहां 0 सबसे काला है और 255 सबसे हल्का है। 128 से अधिक के मूल्यों को प्रकाश द्वारा माना जाता है tinycolor। (@ pau.moreno और @Alnitak द्वारा टिप्पणियों से बेशर्मी से कॉपी की गई)


12
थोड़ी देर में जावास्क्रिप्ट में कुछ अच्छा सा हेरफेर नहीं देखा है। सुन्दर सामान। en.wikipedia.org/wiki/Rec._709#Luma_coefficients
jbabey

2
अच्छा कोड, लेकिन परीक्षण के बाद मैं var luma = (r + g + b) / 3 सुझाता हूं; if (luma <128) {// अधिक उपयोगी होगा। }
टेरी लिन

2
@TerryLin क्यों? दिए गए गुणांक मानक ITU मान हैं जो इस तथ्य की अनुमति देते हैं कि हरे रंग को लाल (और फिर नीला) की तुलना में अधिक उज्ज्वल माना जाता है
अलनीतक

1
परिणामी lumaमूल्य सीमा है 0..255, जहां 0सबसे अंधेरा है और 255सबसे हल्का है (तीन गुणांक एक के बराबर हैं)।
pau.moreno

1
मई 2014 के बाद से ही @gabssnake, और isDark()दहलीज हार्ड-कोडेड है 128 पर
Alnitak

21

TinyColor पुस्तकालय (आप पहले से ही यह उल्लेख किया है) का निरीक्षण और उनके बीच रंग से छेड़छाड़, के लिए कई कार्य प्रदान करता है:


15

मुझे यह WooCommerce Wordpress PHP फ़ंक्शन ( wc_hex_is_light ) मिला और मैंने जावास्क्रिप्ट में बदल दिया। ठीक काम करता है!

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! मैंने कई रंगों के साथ इसका परीक्षण किया, इन सभी के साथ पहचान सही थी :)
डेविड दाल बुस्को

colorIsDarkOrLight (रंग) {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; } और {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; },
पेड्रो हेनरिक

हेक्स 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. तीनों का औसत लें।
  4. कुछ भारित औसत का उपयोग करें जैसा कि अन्य लोगों ने यहां सुझाया है।

AFAIK केवल विकिपीडिया पृष्ठ पर वर्णित लूमा गणना एक धारणा-आधारित मॉडल है।
अलनीतक

2
भौतिक प्रकाश ऊर्जा और कथित चमक के बीच अंतर को इंगित करना अच्छा है, लेकिन मुझे लगता है कि आपने चीजों को मिलाया है। आपके द्वारा जोड़े गए विकिपीडिया लेख के अनुभाग में एक चौथा बुलेट बिंदु है, जो बताता है कि " ल्युमा, वाई uma का उपयोग एक हल्के आयाम के रूप में अधिक प्रासंगिक रूप से प्रासंगिक विकल्प है" (जोर मेरा) और फिर Alititak के प्रस्तुत सूत्र को देने के लिए आगे बढ़ता है और रॉबिन के जवाब। दूसरे शब्दों में, आपके द्वारा छोड़ी और अनुशंसित की गई विधि वह है जो मानव बोध से सर्वश्रेष्ठ रूप से मेल खाती है।
जॉन वाई

@ जॉन हाँ, यही मैं कहना चाह रहा था - वह केवल एक ही बचा है जो वास्तव में उसके उत्तर से मेल खाता है।
अलनीतक

हाँ, पता चला कि मैं यहाँ केवल एक ही उलझन में था। मैं उस के साथ ठीक हूं :) मैं सिर्फ यह चाहता था कि ऊर्जा और धारणा के बीच एक अलग बिंदु हो। मैं अपने उत्तर को तदनुसार अपडेट करूंगा।
डेविड गुयेन

4

हेक्स के साथ यह काम करता है उदा #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);

@ विवेक ऐसा इसलिए है क्योंकि आपको पूर्ण हेक्स मान (# 000000 और #ffffff) का उपयोग करने की आवश्यकता है
TheCrazyProfistr

2

एक संभावित उपाय यह होगा कि आप अपने रंग को RGB से HSB में बदलें । एचएसबी का अर्थ है ह्यू, संतृप्ति और चमक (जिसे एचएसवी भी कहा जाता है, जहां वी मूल्य के लिए है)। फिर आपके पास जांचने के लिए सिर्फ एक पैरामीटर है: चमक।


1

मुझे लगता है कि यह बातचीत कुछ साल पुरानी है, लेकिन यह अभी भी प्रासंगिक है। मैं यह जोड़ना चाहता था कि मेरी टीम जावा (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;
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.