Programing

배경색을 기준으로 글꼴 색 결정

lottogame 2020. 4. 21. 08:19
반응형

배경색을 기준으로 글꼴 색 결정


사용자가 일부 섹션의 배경색을 사용자 정의 할 수 있지만 글꼴 색상이 아닌 옵션 색상을 사용자 정의 할 수있는 시스템 (예 : 옵션 수를 최소로 유지)을 사용하는 경우 프로그래밍 방식으로 "조명"또는 " 어두운 "글꼴 색상이 필요합니까?

알고리즘이 있다고 확신하지만 색상, 광도 등을 스스로 알아낼 수는 없습니다.


비슷한 문제가 발생했습니다. 컬러 스케일 / 히트 맵에 텍스트 레이블을 표시하기 위해 대비 글꼴 색상을 선택하는 좋은 방법을 찾아야했습니다. 그것은 보편적 인 방법이어야하고 생성 된 색상은 "보기 좋게"되어야했습니다. 이는 단순한 보완적인 색상 생성이 좋은 해결책이 아니라는 것을 의미합니다. 때로는보기 어렵고 매우 강렬한 색상을 생성하기도했습니다.

오랜 시간 동안 테스트하고이 문제를 해결하려고 시도한 후 "어두운"색은 흰색 글꼴을, "밝은"색은 검정색 글꼴을 선택하는 것이 가장 좋은 방법이라는 것을 알았습니다.

다음은 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을 "지각 휘도"로 변경 했습니다. 정말 좋아 보입니다! 이미 소프트웨어로 구현했는데 멋지게 보입니다.

Edit 2 @WebSeed는이 알고리즘의 훌륭한 작업 예를 제공했습니다. http://codepen.io/WebSeed/full/pvgqEq/


누군가가 더 짧고 이해하기 쉬운 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().)


@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;
}

Gacek의 답변에 대한 Swift 구현 :

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)
}

자바 스크립트 [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;
};

이것은 유용한 답변입니다. 감사합니다!

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 );

}

이제 알고리즘을 사용하여 메뉴 링크의 호버 색상을 자동으로 만드는 방법을 알아 냈습니다. 가벼운 헤더는 더 호버링되며 그 반대도 마찬가지입니다.


이 게시물에 감사드립니다.

관심있는 사람이라면 델파이에서 그 함수의 예를 보자.

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;

당신이 그것을 쓰고 싶지 않다면 추악한 파이썬 :)

'''
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'

나는 같은 문제가 있었지만 PHP 로 개발해야했다 . @Garek의 솔루션을 사용 했으며이 답변을 사용했습니다 .HEX 색상 코드를 RGB로 변환하려면 PHP에서 16 진수 색상을 RGB 값 으로 변환하십시오.

그래서 나는 그것을 공유하고 있습니다.

주어진 Background HEX 색상 으로이 기능을 사용하고 싶었지만 항상 '#'부터 시작하는 것은 아닙니다.

//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;
}

objective-c 구현

+ (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];
}

iOS Swift 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
}

스위프트 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쿼리에 대한 더 나은 테스트 베드라는 것을 알았습니다.


플러터 구현

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;
}

시각적 효과를 위해 색 공간을 조작하는 경우 일반적으로 RGB보다 HSL (색조, 채도 및 명도)에서 작업하기가 더 쉽습니다. 자연스럽게 만족스러운 효과를 내기 위해 RGB로 색상을 옮기는 것은 개념적으로 매우 어려운 경향이 있지만, HSL로 변환하고 조작 한 다음 다시 다시 변환하는 것은 개념 상 더 직관적이며 항상 더 나은 결과를 제공합니다.

Wikipedia에는 HSL과 밀접하게 관련된 HSV에 대한 좋은 소개 가 있습니다. 그리고 그물 주위에 변환을 수행하는 무료 코드가 있습니다 (예를 들어 여기에 자바 스크립트 구현이 있습니다 )

사용하는 정확한 변환은 맛의 문제이지만 개인적으로 Hue and Lightness 구성 요소를 반전하면 첫 번째 근사치로 좋은 고 대비 색상을 생성해야하지만 더 미묘한 효과를 쉽게 얻을 수 있다고 생각했습니다.


모든 색조 배경에 임의의 색조 텍스트를 사용하고 읽을 수 있는지 확인하십시오. 나는 항상 그것을한다. Javascript에는 읽을 수있는 텍스트 (색상 – STW * )에 대한 공식이 있습니다. 링크에서 언급 한 것처럼 공식은 역 감마 조정 계산의 변형이지만 약간 더 관리하기 쉬운 IMHO입니다. 해당 링크의 오른쪽에있는 메뉴와 관련 페이지는 텍스트와 배경에 대해 무작위로 생성 된 색상을 사용하며 항상 읽을 수 있습니다. 예, 분명히 할 수 있습니다. 문제 없습니다.


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
}

알파를 캡처하는 Android 변형입니다.

(@ thomas-vos 감사합니다)

/**
 * Returns a colour best suited to contrast with the input colour.
 *
 * @param colour
 * @return
 */
@ColorInt
public static int contrastingColour(@ColorInt int colour) {
    // XXX https://stackoverflow.com/questions/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);
}

참고 URL : https://stackoverflow.com/questions/1855884/determine-font-color-based-on-background-color

반응형