पृष्ठभूमि रंग के आधार पर फ़ॉन्ट रंग निर्धारित करें


248

एक ऐसी प्रणाली (उदाहरण के लिए एक वेबसाइट) दी गई है जो उपयोगकर्ता को कुछ खंड के लिए पृष्ठभूमि रंग को अनुकूलित करने देती है, लेकिन फ़ॉन्ट रंग (न्यूनतम के लिए विकल्पों की संख्या रखने के लिए) नहीं, क्या प्रोग्राम "लाइट" या "" निर्धारित करने का एक तरीका है गहरा "फ़ॉन्ट रंग आवश्यक है?

मुझे यकीन है कि कुछ एल्गोरिथ्म है, लेकिन मुझे रंगों, चमक, आदि के बारे में पर्याप्त नहीं पता है।

जवाबों:


447

मुझे भी ऐसी ही समस्या का सामना करना पड़ा। मुझे colorcales / heatmaps पर पाठ लेबल प्रदर्शित करने के लिए विपरीत फ़ॉन्ट रंग का चयन करने का एक अच्छा तरीका खोजना पड़ा। इसे सार्वभौमिक विधि होना था और उत्पन्न रंग को "गुड लुकिंग" होना था, जिसका अर्थ है कि सरल उत्पादक पूरक रंग अच्छा समाधान नहीं था - कभी-कभी यह अजीब, बहुत गहन रंग उत्पन्न करता था जो देखने और पढ़ने में कठिन थे।

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

यहाँ C # में उपयोग किए जा रहे फ़ंक्शन का एक उदाहरण है:

Color ContrastColor(Color color)
{
    int d = 0;

    // Counting the perceptive luminance - human eye favors green color... 
    double luminance = ( 0.299 * color.R + 0.587 * color.G + 0.114 * color.B)/255;

    if (luminance > 0.5)
       d = 0; // bright colors - black font
    else
       d = 255; // dark colors - white font

    return  Color.FromArgb(d, d, d);
}

इसका परीक्षण कई विभिन्न रंगों (इंद्रधनुष, ग्रेस्केल, हीट, आइस, और कई अन्य) के लिए किया गया था और यह एकमात्र "सार्वभौमिक" विधि है जिसका मुझे पता चला।

संपादित
गिनती के सूत्र बदल दिया a"बोधगम्य luminance" करने के लिए - यह वास्तव में बेहतर लग रहा है! पहले से ही इसे मेरे सॉफ़्टवेयर में लागू किया गया, बहुत अच्छा लग रहा है।

संपादित करें 2 @WebSeed ने इस एल्गोरिथ्म का एक शानदार काम किया उदाहरण: http://codepen.io/WebSeed/full/pvgqEq/


14
यह शायद महत्वपूर्ण नहीं है, लेकिन आप ब्राइट स्टैकओवरफ्लो की गणना करने के लिए एक बेहतर कार्य कर सकते हैं। http: //www.questions/596216/…
जोश ली

1
ऐसा लगता है कि यह बिल्कुल सही होगा।
जोसेफ डेगले

वास्तव में आज मुझे जो चाहिए था।
क्रिस डब्ल्यू

आपके अवधारणात्मक ल्यूमिनेंस का भार कहां से आता है?
Mat

इस उत्तर से: stackoverflow.com/questions/596216/…
Gacek

23

यदि कोई व्यक्ति GaceK के उत्तर के संस्करण को समझना आसान हो जाता है, तो बस :

public Color ContrastColor(Color iColor)
{
   // Calculate the perceptive luminance (aka luma) - human eye favors green color... 
   double luma = ((0.299 * iColor.R) + (0.587 * iColor.G) + (0.114 * iColor.B)) / 255;

   // Return black for bright colors, white for dark colors
   return luma > 0.5 ? Color.Black : Color.White;
}

नोट: मैंने ल्युमा वैल्यू के उलटा को हटा दिया (चमकीले रंगों को अधिक मूल्य देने के लिए, जो मुझे अधिक स्वाभाविक लगता है और वह 'डिफ़ॉल्ट' गणना पद्धति भी है।

मैं से Gacek के रूप में ही इस्तेमाल किया स्थिरांक यहाँ वे मेरे लिए महान काम किया के बाद से।

(आप निम्नलिखित हस्ताक्षर का उपयोग करके इसे एक्सटेंशन विधि के रूप में भी लागू कर सकते हैं :

public static Color ContrastColor(this Color iColor)

तब आप इसे कॉल कर सकते हैं foregroundColor = background.ContrastColor()।)


11

धन्यवाद @Gacek । यहाँ Android के लिए एक संस्करण है:

@ColorInt
public static int getContrastColor(@ColorInt int color) {
    // Counting the perceptive luminance - human eye favors green color...
    double a = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255;

    int d;
    if (a < 0.5) {
        d = 0; // bright colors - black font
    } else {
        d = 255; // dark colors - white font
    }

    return Color.rgb(d, d, d);
}

और एक बेहतर (कम) संस्करण:

@ColorInt
public static int getContrastColor(@ColorInt int color) {
    // Counting the perceptive luminance - human eye favors green color...
    double a = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255;
    return a < 0.5 ? Color.BLACK : Color.WHITE;
}

यह, यहां तक कि छोटा और आसान को पढ़ने के लिए हो सकता है अगर आप @Marcus Mangelsdorf (के परिवर्तन से छुटकारा पाने के लागू होता 1 - ...हिस्सा है और नाम बदलने aके लिएluminance
Ridcully

पहले एक का उपयोग करते हुए, आप अल्फा पर भी कब्जा कर सकते हैं।
ब्रिल पप्पिन

9

गेसक के जवाब का मेरा स्विफ्ट कार्यान्वयन:

func contrastColor(color: UIColor) -> UIColor {
    var d = CGFloat(0)

    var r = CGFloat(0)
    var g = CGFloat(0)
    var b = CGFloat(0)
    var a = CGFloat(0)

    color.getRed(&r, green: &g, blue: &b, alpha: &a)

    // Counting the perceptive luminance - human eye favors green color...
    let luminance = 1 - ((0.299 * r) + (0.587 * g) + (0.114 * b))

    if luminance < 0.5 {
        d = CGFloat(0) // bright colors - black font
    } else {
        d = CGFloat(1) // dark colors - white font
    }

    return UIColor( red: d, green: d, blue: d, alpha: a)
}

स्विफ्ट में, चूंकि r / g / b CGFloats हैं, इसलिए आपको luminance की गणना करने के लिए "/ 255" की आवश्यकता नहीं है: luminance = 1 - ((0.299 * r) + (0.587 * g) + (0.114 * b)
सुपरडूंगटैंगो

8

जावास्क्रिप्ट [ES2015]

const hexToLuma = (colour) => {
    const hex   = colour.replace(/#/, '');
    const r     = parseInt(hex.substr(0, 2), 16);
    const g     = parseInt(hex.substr(2, 2), 16);
    const b     = parseInt(hex.substr(4, 2), 16);

    return [
        0.299 * r,
        0.587 * g,
        0.114 * b
    ].reduce((a, b) => a + b) / 255;
};

6

इस पोस्ट के लिए धन्यवाद।

जो कोई भी दिलचस्पी ले सकता है, यहां डेल्फी में उस फ़ंक्शन का एक उदाहरण है:

function GetContrastColor(ABGColor: TColor): TColor;
var
  ADouble: Double;
  R, G, B: Byte;
begin
  if ABGColor <= 0 then
  begin
    Result := clWhite;
    Exit; // *** EXIT RIGHT HERE ***
  end;

  if ABGColor = clWhite then
  begin
    Result := clBlack;
    Exit; // *** EXIT RIGHT HERE ***
  end;

  // Get RGB from Color
  R := GetRValue(ABGColor);
  G := GetGValue(ABGColor);
  B := GetBValue(ABGColor);

  // Counting the perceptive luminance - human eye favors green color...
  ADouble := 1 - (0.299 * R + 0.587 * G + 0.114 * B) / 255;

  if (ADouble < 0.5) then
    Result := clBlack  // bright colors - black font
  else
    Result := clWhite;  // dark colors - white font
end;

अंतिम पंक्ति से 4 वें में एक छोटी सी त्रुटि है। परिणाम: = clBlack के बाद अर्ध-बृहदान्त्र नहीं होना चाहिए;
एंडी के

5

यह एक ऐसा मददगार जवाब है। इसके लिए धन्यवाद्!

मैं एक SCSS संस्करण साझा करना चाहता हूं:

@function is-color-light( $color ) {

  // Get the components of the specified color
  $red: red( $color );
  $green: green( $color );
  $blue: blue( $color );

  // Compute the perceptive luminance, keeping
  // in mind that the human eye favors green.
  $l: 1 - ( 0.299 * $red + 0.587 * $green + 0.114 * $blue ) / 255;
  @return ( $l < 0.5 );

}

अब यह पता लगाना है कि मेनू लिंक के लिए ऑटो-हॉवर रंगों के लिए एल्गोरिथ्म का उपयोग कैसे करें। लाइट हेडर को अधिक गहरा होवर मिलता है, और इसके विपरीत।


3

स्पंदन कार्यान्वयन

Color contrastColor(Color color) {
  if (color == Colors.transparent || color.alpha < 50) {
    return Colors.black;
  }
  double luminance = (0.299 * color.red + 0.587 * color.green + 0.114 * color.blue) / 255;
  return luminance > 0.5 ? Colors.black : Colors.white;
}

मैंने जो कुछ किया वह सब 'स्थिर' था। धन्यवाद!
पीट एल्विन

2

बदसूरत अजगर अगर आप इसे लिखने की तरह महसूस नहीं करते हैं :)

'''
Input a string without hash sign of RGB hex digits to compute
complementary contrasting color such as for fonts
'''
def contrasting_text_color(hex_str):
    (r, g, b) = (hex_str[:2], hex_str[2:4], hex_str[4:])
    return '000' if 1 - (int(r, 16) * 0.299 + int(g, 16) * 0.587 + int(b, 16) * 0.114) / 255 < 0.5 else 'fff'

2

मुझे भी यही समस्या थी लेकिन मुझे इसे PHP में विकसित करना था । मैंने @ गारेक के समाधान का उपयोग किया और मैंने इस उत्तर का भी उपयोग किया: हेक्स रंग को PHP में RGB मानों में परिवर्तित करके HEX रंग कोड को RGB में कनवर्ट करें।

इसलिए मैं इसे साझा कर रहा हूं।

मैं दिए गए बैकग्राउंड एचईएक्स रंग के साथ इस फ़ंक्शन का उपयोग करना चाहता था, लेकिन हमेशा '#' से शुरू नहीं हुआ।

//So it can be used like this way:
$color = calculateColor('#804040');
echo $color;

//or even this way:
$color = calculateColor('D79C44');
echo '<br/>'.$color;

function calculateColor($bgColor){
    //ensure that the color code will not have # in the beginning
    $bgColor = str_replace('#','',$bgColor);
    //now just add it
    $hex = '#'.$bgColor;
    list($r, $g, $b) = sscanf($hex, "#%02x%02x%02x");
    $color = 1 - ( 0.299 * $r + 0.587 * $g + 0.114 * $b)/255;

    if ($color < 0.5)
        $color = '#000000'; // bright colors - black font
    else
        $color = '#ffffff'; // dark colors - white font

    return $color;
}

1

Kotlin / Android एक्सटेंशन के रूप में:

fun Int.getContrastColor(): Int {
    // Counting the perceptive luminance - human eye favors green color...
    val a = 1 - (0.299 * Color.red(this) + 0.587 * Color.green(this) + 0.114 * Color.blue(this)) / 255
    return if (a < 0.5) Color.BLACK else Color.WHITE
}

1

उद्देश्य-सी के लिए एक कार्यान्वयन

+ (UIColor*) getContrastColor:(UIColor*) color {
    CGFloat red, green, blue, alpha;
    [color getRed:&red green:&green blue:&blue alpha:&alpha];
    double a = ( 0.299 * red + 0.587 * green + 0.114 * blue);
    return (a > 0.5) ? [[UIColor alloc]initWithRed:0 green:0 blue:0 alpha:1] : [[UIColor alloc]initWithRed:255 green:255 blue:255 alpha:1];
}

2
अन्य उपयोगकर्ताओं को यह बताने के लिए आपको यहां कुछ विवरण जोड़ना चाहिए कि आपके कोड में क्या चल रहा है
माइकल

1

iOS स्विफ्ट 3.0 (UIColor एक्सटेंशन):

func isLight() -> Bool
{
    if let components = self.cgColor.components, let firstComponentValue = components[0], let secondComponentValue = components[1], let thirdComponentValue = components[2] {
        let firstComponent = (firstComponentValue * 299)
        let secondComponent = (secondComponentValue * 587)
        let thirdComponent = (thirdComponentValue * 114)
        let brightness = (firstComponent + secondComponent + thirdComponent) / 1000

        if brightness < 0.5
        {
            return false
        }else{
            return true
        }
    }  

    print("Unable to grab components and determine brightness")
    return nil
}

1
समारोह अपेक्षित रूप से कर रहा है लेकिन
लिटिंग

1
महान, नीचे स्विफ्ट 4 के लिए मेरा उदाहरण देखें, आप कोड में कमी देख सकते हैं
रिचपेज़

1

स्विफ्ट 4 उदाहरण:

extension UIColor {

    var isLight: Bool {
        let components = cgColor.components

        let firstComponent = ((components?[0]) ?? 0) * 299
        let secondComponent = ((components?[1]) ?? 0) * 587
        let thirdComponent = ((components?[2]) ?? 0) * 114
        let brightness = (firstComponent + secondComponent + thirdComponent) / 1000

        return !(brightness < 0.6)
    }

}

अद्यतन - पाया 0.6गया कि क्वेरी के लिए एक बेहतर परीक्षण बिस्तर था


यह वास्तव में कई स्थितियों में विफल होने की संभावना है, क्योंकि यह एक RGB रंग स्थान मानता है। CGColor.componentsरंगों की जगह के आधार पर तत्वों की संख्या भिन्न होती है: उदाहरण के लिए, UIColor.whiteजब एक CGColor को डाला जाता है, तो केवल दो होते हैं: [1.0, 1.0]एक पूर्ण अल्फा के साथ ग्रेस्केल (पूरी तरह से सफेद) रंग का प्रतिनिधित्व करते हैं। एक UIColor के RGB तत्वों को निकालने का एक बेहतर साधन हैUIColor.getRed(_ red:, green:, blue:, alpha:)
स्कॉट मैथ्मैन

1

ध्यान दें कि गूगल क्लोजर लाइब्रेरी में इसके लिए एक एल्गोरिथ्म है जो w3c अनुशंसा का संदर्भ देता है: http://www.w3.org/TR/AERT#color-contrast । हालाँकि, इस API में आप शुरुआती बिंदु के रूप में सुझाए गए रंगों की एक सूची प्रदान करते हैं।

/**
 * Find the "best" (highest-contrast) of the suggested colors for the prime
 * color. Uses W3C formula for judging readability and visual accessibility:
 * http://www.w3.org/TR/AERT#color-contrast
 * @param {goog.color.Rgb} prime Color represented as a rgb array.
 * @param {Array<goog.color.Rgb>} suggestions Array of colors,
 *     each representing a rgb array.
 * @return {!goog.color.Rgb} Highest-contrast color represented by an array.
 */
goog.color.highContrast = function(prime, suggestions) {
  var suggestionsWithDiff = [];
  for (var i = 0; i < suggestions.length; i++) {
    suggestionsWithDiff.push({
      color: suggestions[i],
      diff: goog.color.yiqBrightnessDiff_(suggestions[i], prime) +
          goog.color.colorDiff_(suggestions[i], prime)
    });
  }
  suggestionsWithDiff.sort(function(a, b) { return b.diff - a.diff; });
  return suggestionsWithDiff[0].color;
};


/**
 * Calculate brightness of a color according to YIQ formula (brightness is Y).
 * More info on YIQ here: http://en.wikipedia.org/wiki/YIQ. Helper method for
 * goog.color.highContrast()
 * @param {goog.color.Rgb} rgb Color represented by a rgb array.
 * @return {number} brightness (Y).
 * @private
 */
goog.color.yiqBrightness_ = function(rgb) {
  return Math.round((rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000);
};


/**
 * Calculate difference in brightness of two colors. Helper method for
 * goog.color.highContrast()
 * @param {goog.color.Rgb} rgb1 Color represented by a rgb array.
 * @param {goog.color.Rgb} rgb2 Color represented by a rgb array.
 * @return {number} Brightness difference.
 * @private
 */
goog.color.yiqBrightnessDiff_ = function(rgb1, rgb2) {
  return Math.abs(
      goog.color.yiqBrightness_(rgb1) - goog.color.yiqBrightness_(rgb2));
};


/**
 * Calculate color difference between two colors. Helper method for
 * goog.color.highContrast()
 * @param {goog.color.Rgb} rgb1 Color represented by a rgb array.
 * @param {goog.color.Rgb} rgb2 Color represented by a rgb array.
 * @return {number} Color difference.
 * @private
 */
goog.color.colorDiff_ = function(rgb1, rgb2) {
  return Math.abs(rgb1[0] - rgb2[0]) + Math.abs(rgb1[1] - rgb2[1]) +
      Math.abs(rgb1[2] - rgb2[2]);
};

0

यदि आप दृश्य प्रभाव के लिए रंग स्थानों में हेरफेर कर रहे हैं, तो यह आम तौर पर RGB (Hue, Saturation और Lightness) में RGB की तुलना में काम करना आसान होता है। स्वाभाविक रूप से मनभावन प्रभाव देने के लिए RGB में रंगों को ले जाना काफी अवधारणात्मक रूप से कठिन होता है, जबकि HSL में परिवर्तित होते हुए, वहां हेरफेर करते हुए, फिर से वापस बाहर लौटना अवधारणा में अधिक सहज होता है और हमेशा बेहतर दिखने वाले परिणाम देता है।

विकिपीडिया का HSL और निकटता से संबंधित HSV से अच्छा परिचय है। और रूपांतरण करने के लिए नेट के आसपास मुफ्त कोड है (उदाहरण के लिए यहां एक जावास्क्रिप्ट कार्यान्वयन है )

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


1
हां, लेकिन यह भी विचार करें कि मानव आंख हरे रंग की तुलना में अन्य रंगों की तुलना में अधिक प्रभावी ढंग से देख सकती है, और नीला कम (इसलिए यही कारण है कि नीले रंग को छवि स्वरूपों में कम रंग मिलते हैं)।
वचर्जिन

1
वास्तव में। यदि हम HSL में जाने जा रहे हैं, तो हम YUV में पूरी छलांग लगा सकते हैं और मानवीय धारणा को ध्यान में रख सकते हैं।
डेविड ब्रैडबरी

0

आप किसी भी ह्यू पृष्ठभूमि पर कोई भी पाठ लिख सकते हैं और यह सुनिश्चित कर सकते हैं कि यह सुपाठ्य है। मुझे हर व़क्त यह करना है। इसके लिए एक फॉर्मूला है जावास्क्रिप्ट इन रीडेबल टेक्स्ट ऑन कलर- STW * जैसा कि उस लिंक पर लिखा है , फॉर्मूला उलटा-गामा समायोजन गणना पर भिन्नता है, हालांकि थोड़ा अधिक प्रबंधनीय IMHO है। उस लिंक के दाईं ओर स्थित मेनू और उसके संबंधित पृष्ठ पाठ और पृष्ठभूमि के लिए यादृच्छिक रूप से उत्पन्न रंगों का उपयोग करते हैं, हमेशा सुपाठ्य। तो हाँ, स्पष्ट रूप से यह किया जा सकता है, कोई बात नहीं।


0

एक Android भिन्नता जो अल्फा को भी पकड़ लेती है।

(साभार @ थोमस-वोस)

/**
 * Returns a colour best suited to contrast with the input colour.
 *
 * @param colour
 * @return
 */
@ColorInt
public static int contrastingColour(@ColorInt int colour) {
    // XXX /programming/1855884/determine-font-color-based-on-background-color

    // Counting the perceptive luminance - human eye favors green color...
    double a = 1 - (0.299 * Color.red(colour) + 0.587 * Color.green(colour) + 0.114 * Color.blue(colour)) / 255;
    int alpha = Color.alpha(colour);

    int d = 0; // bright colours - black font;
    if (a >= 0.5) {
        d = 255; // dark colours - white font
    }

    return Color.argb(alpha, d, d, d);
}

0

base@ Gacek के उत्तर पाने के लिए R संस्करण luminance(आप अपनी खुद की दहलीज आसानी से लागू कर सकते हैं)

# vectorized
luminance = function(col) c(c(.299, .587, .114) %*% col2rgb(col)/255)

उपयोग:

luminance(c('black', 'white', '#236FAB', 'darkred', '#01F11F'))
# [1] 0.0000000 1.0000000 0.3730039 0.1629843 0.5698039

0

गेसक के जवाब के आधार पर , और WAVE ब्राउज़र एक्सटेंशन के साथ @ WebSeed के उदाहरण का विश्लेषण करने के बाद , मैं निम्नलिखित संस्करण के साथ आया हूं जो विपरीत अनुपात के आधार पर काले या सफेद पाठ को चुनता है (जैसा कि W3C की वेब सामग्री पहुंच दिशानिर्देश (WCAG) 2.1 में परिभाषित है ) ल्यूमिनेन्स के बजाय।

यह कोड है (जावास्क्रिप्ट में):

// As defined in WCAG 2.1
var relativeLuminance = function (R8bit, G8bit, B8bit) {
  var RsRGB = R8bit / 255.0;
  var GsRGB = G8bit / 255.0;
  var BsRGB = B8bit / 255.0;

  var R = (RsRGB <= 0.03928) ? RsRGB / 12.92 : Math.pow((RsRGB + 0.055) / 1.055, 2.4);
  var G = (GsRGB <= 0.03928) ? GsRGB / 12.92 : Math.pow((GsRGB + 0.055) / 1.055, 2.4);
  var B = (BsRGB <= 0.03928) ? BsRGB / 12.92 : Math.pow((BsRGB + 0.055) / 1.055, 2.4);

  return 0.2126 * R + 0.7152 * G + 0.0722 * B;
};

var blackContrast = function(r, g, b) {
  var L = relativeLuminance(r, g, b);
  return (L + 0.05) / 0.05;
};

var whiteContrast = function(r, g, b) {
  var L = relativeLuminance(r, g, b);
  return 1.05 / (L + 0.05);
};

// If both options satisfy AAA criterion (at least 7:1 contrast), use preference
// else, use higher contrast (white breaks tie)
var chooseFGcolor = function(r, g, b, prefer = 'white') {
  var Cb = blackContrast(r, g, b);
  var Cw = whiteContrast(r, g, b);
  if(Cb >= 7.0 && Cw >= 7.0) return prefer;
  else return (Cb > Cw) ? 'black' : 'white';
};

एक कार्यशील उदाहरण मेरे वेबसाइड के कोडपेन के कांटे में पाया जा सकता है , जो WAVE में शून्य कम विपरीत त्रुटियां पैदा करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.