302

この例のような画像を表示したい代替テキスト

塗りつぶしの色は、16 進数の色を持つデータベース内のフィールドによって決定されます (例: ClassX -> Color: #66FFFF)。ここで、選択した色 (上の画像のように) で塗りつぶしの上にデータを表示したいのですが、色が暗いか明るいかを知る必要があるため、単語が白か黒かがわかります。方法はありますか?tks

4

24 に答える 24

466

同様の質問に対する私の回答に基づいています。

個々の赤、緑、青の強度を取得するには、16 進コードを 3 つの部分に分割する必要があります。コードの各 2 桁は、16 進数 (base-16) 表記の値を表します。変換の詳細についてはここでは触れませんが、調べるのは簡単です。

個々の色の強度を取得したら、色の全体的な強度を決定し、対応するテキストを選択できます。

if (red*0.299 + green*0.587 + blue*0.114) > 186 use #000000 else use #ffffff

186 というしきい値は理論に基づいていますが、好みに合わせて調整できます。コメントに基づいて、150 のしきい値が適切に機能する可能性があります。


編集:上記はシンプルで、かなりうまく機能し、ここ StackOverflow で十分に受け入れられているようです。ただし、以下のコメントの 1 つは、状況によっては W3C ガイドラインに準拠しない可能性があることを示しています。これにより、ガイドラインに基づいて常に最高のコントラストを選択する修正された形式を導き出します。W3C の規則に準拠する必要がない場合は、上記のより単純な式を使用します。

W3C 勧告でコントラストを表す公式は です(L1 + 0.05) / (L2 + 0.05)。ここL1で、 は最も明るい色L2の輝度、 は最も暗い色の輝度を 0.0 ~ 1.0 のスケールで表したものです。黒の輝度は 0.0、白は 1.0 であるため、これらの値を代入することで、最もコントラストが高い輝度を決定できます。黒のコントラストが白のコントラストより大きい場合は黒を使用し、それ以外の場合は白を使用します。テストとしてテストしている色の輝度を考えると、次のようLになります。

if (L + 0.05) / (0.0 + 0.05) > (1.0 + 0.05) / (L + 0.05) use #000000 else use #ffffff

これは、代数的に次のように簡略化されます。

if L > sqrt(1.05 * 0.05) - 0.05

またはおおよそ:

if L > 0.179 use #000000 else use #ffffff

あとは を計算するだけですL。その式はガイドラインにも記載されており、sRGB からリニア RGB への変換に続いて、輝度に関するITU-R 勧告 BT.709のように見えます。

for each c in r,g,b:
    c = c / 255.0
    if c <= 0.03928 then c = c/12.92 else c = ((c+0.055)/1.055) ^ 2.4
L = 0.2126 * r + 0.7152 * g + 0.0722 * b

0.179 のしきい値は、W3C ガイドラインに関連付けられているため、変更しないでください。結果が気に入らない場合は、上記のより単純な式を試してください。

于 2010-10-15T14:11:24.650 に答える
62

このコードは私のものではないため、私は信用しませんが、他の人が将来すぐに見つけられるようにここに残します。

Mark Ransoms の回答に基づいて、単純なバージョンのコード スニペットを次に示します。

function pickTextColorBasedOnBgColorSimple(bgColor, lightColor, darkColor) {
  var color = (bgColor.charAt(0) === '#') ? bgColor.substring(1, 7) : bgColor;
  var r = parseInt(color.substring(0, 2), 16); // hexToR
  var g = parseInt(color.substring(2, 4), 16); // hexToG
  var b = parseInt(color.substring(4, 6), 16); // hexToB
  return (((r * 0.299) + (g * 0.587) + (b * 0.114)) > 186) ?
    darkColor : lightColor;
}

高度なバージョンのコード スニペットは次のとおりです。

function pickTextColorBasedOnBgColorAdvanced(bgColor, lightColor, darkColor) {
  var color = (bgColor.charAt(0) === '#') ? bgColor.substring(1, 7) : bgColor;
  var r = parseInt(color.substring(0, 2), 16); // hexToR
  var g = parseInt(color.substring(2, 4), 16); // hexToG
  var b = parseInt(color.substring(4, 6), 16); // hexToB
  var uicolors = [r / 255, g / 255, b / 255];
  var c = uicolors.map((col) => {
    if (col <= 0.03928) {
      return col / 12.92;
    }
    return Math.pow((col + 0.055) / 1.055, 2.4);
  });
  var L = (0.2126 * c[0]) + (0.7152 * c[1]) + (0.0722 * c[2]);
  return (L > 0.179) ? darkColor : lightColor;
}

それらを使用するには、次のように呼び出します。

var color = '#EEACAE' // this can be any color
pickTextColorBasedOnBgColorSimple(color, '#FFFFFF', '#000000');

Alxまた、ありがとうございchetstoneます。

于 2017-01-05T17:31:58.530 に答える
23

これ(JavaScriptコード)はどうですか?

/**
 * Get color (black/white) depending on bgColor so it would be clearly seen.
 * @param bgColor
 * @returns {string}
 */
getColorByBgColor(bgColor) {
    if (!bgColor) { return ''; }
    return (parseInt(bgColor.replace('#', ''), 16) > 0xffffff / 2) ? '#000' : '#fff';
}
于 2015-11-24T10:16:09.243 に答える
8

Android用のJavaでの私のソリューションは次のとおりです。

// Put this method in whichever class you deem appropriate
// static or non-static, up to you.
public static int getContrastColor(int colorIntValue) {
    int red = Color.red(colorIntValue);
    int green = Color.green(colorIntValue);
    int blue = Color.blue(colorIntValue);
    double lum = (((0.299 * red) + ((0.587 * green) + (0.114 * blue))));
    return lum > 186 ? 0xFF000000 : 0xFFFFFFFF;
}

// Usage
// If Color is represented as HEX code:
String colorHex = "#484588";
int color = Color.parseColor(colorHex);

// Or if color is Integer:
int color = 0xFF484588;

// Get White (0xFFFFFFFF) or Black (0xFF000000)
int contrastColor = WhateverClass.getContrastColor(color);
于 2016-08-19T05:42:57.420 に答える
6

これは、UIColor の拡張としての Mark Ransom の回答の迅速なバージョンです。

extension UIColor {

// Get the rgba components in CGFloat
var rgba: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
    var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0

    getRed(&red, green: &green, blue: &blue, alpha: &alpha)

    return (red, green, blue, alpha)
}

/// Return the better contrasting color, white or black
func contrastColor() -> UIColor {
    let rgbArray = [rgba.red, rgba.green, rgba.blue]

    let luminanceArray = rgbArray.map({ value -> (CGFloat) in
        if value < 0.03928 {
            return (value / 12.92)
        } else {
            return (pow( (value + 0.55) / 1.055, 2.4) )
        }
    })

    let luminance = 0.2126 * luminanceArray[0] +
        0.7152 * luminanceArray[1] +
        0.0722 * luminanceArray[2]

    return luminance > 0.179 ? UIColor.black : UIColor.white
} }
于 2018-08-28T15:28:08.360 に答える
2

rgbこの JavaScript 関数を使用して/rgba'white'orに変換し'black'ます。

function getTextColor(rgba) {
    rgba = rgba.match(/\d+/g);
    if ((rgba[0] * 0.299) + (rgba[1] * 0.587) + (rgba[2] * 0.114) > 186) {
        return 'black';
    } else {
        return 'white';
    }
}

これらの形式のいずれかを入力すると、出力'black'または'white'

  • rgb(255,255,255)
  • rgba(255,255,255,0.1)
  • color:rgba(255,255,255,0.1)
  • 255,255,255,0.1
于 2016-09-12T22:29:13.847 に答える
2

これは、要素をクリックしたときに SVG チェックマークの色を変更する単なる例です。クリックされた要素の背景色に基づいて、チェックマークの色を黒または白に設定します。

checkmarkColor: function(el) {
    var self = el;
    var contrast = function checkContrast(rgb) {
        // @TODO check for HEX value

        // Get RGB value between parenthesis, and remove any whitespace
        rgb = rgb.split(/\(([^)]+)\)/)[1].replace(/ /g, '');

        // map RGB values to variables
        var r = parseInt(rgb.split(',')[0], 10),
            g = parseInt(rgb.split(',')[1], 10),
            b = parseInt(rgb.split(',')[2], 10),
            a;

        // if RGBA, map alpha to variable (not currently in use)
        if (rgb.split(',')[3] !== null) {
            a = parseInt(rgb.split(',')[3], 10);
        }

        // calculate contrast of color (standard grayscale algorithmic formula)
        var contrast = (Math.round(r * 299) + Math.round(g * 587) + Math.round(b * 114)) / 1000;

        return (contrast >= 128) ? 'black' : 'white';
    };

    $('#steps .step.color .color-item .icon-ui-checkmark-shadow svg').css({
        'fill': contrast($(self).css('background-color'))
    });
}

onClickExtColor: function(evt) {
    var self = this;

    self.checkmarkColor(evt.currentTarget);
}

https://gist.github.com/dcondrey/183971f17808e9277572

于 2015-10-20T21:57:23.967 に答える
1

私はこのようなことをしたことがありませんが、Hex 7F (FF / 2) の中央値の色に対して各色の値をチェックする関数を作成するのはどうでしょうか。3 つの色のうち 2 つが 7F より大きい場合は、より暗い色を使用しています。

于 2010-10-15T14:03:46.977 に答える
0

を使用すると、受け入れられた回答がAndroidで機能しませんでしたandroidx.compose.ui.graphics.Colorluminance()次に、[0,1] の間の輝度値を返す Android Jetpack Compose の組み込み関数が実際にあることがわかりました。ドキュメントには、「WCAG 2.0、W3C 勧告 2008 年 11 月 11 日に定義された相対輝度の式に基づく」と記載されています。

これが公式のソースコードです。

使用例:

fun Color.generateOnColor()
        : Color {
    return if (luminance() > 0.5f) {
        Color.Black.copy(alpha = .8f)
    } else {
        Color.White
    }
}
于 2021-08-20T18:14:53.243 に答える
0

マークの回答に基づく iOS の Objective-c バージョン コード:

- (UIColor *)contrastForegroundColor {
CGFloat red = 0, green = 0, blue = 0, alpha = 0;
[self getRed:&red green:&green blue:&blue alpha:&alpha];
NSArray<NSNumber *> *rgbArray = @[@(red), @(green), @(blue)];
NSMutableArray<NSNumber *> *parsedRGBArray = [NSMutableArray arrayWithCapacity:rgbArray.count];
for (NSNumber *item in rgbArray) {
    if (item.doubleValue <= 0.03928) {
        [parsedRGBArray addObject:@(item.doubleValue / 12.92)];
    } else {
        double newValue = pow((item.doubleValue + 0.055) / 1.055, 2.4);
        [parsedRGBArray addObject:@(newValue)];
    }
}

double luminance = 0.2126 * parsedRGBArray[0].doubleValue + 0.7152 * parsedRGBArray[1].doubleValue + 0.0722 * parsedRGBArray[2].doubleValue;

return luminance > 0.179 ? UIColor.blackColor : UIColor.whiteColor;
}
于 2018-07-29T01:02:05.253 に答える