ProgramingTip

불투명도가있는 "동등한"색상 찾기

bestdevel 2020. 10. 5. 08:11
반응형

불투명도가있는 "동등한"색상 찾기


"리본"이 다른 단색으로 실행되는 배경색이 가정 해 보겠습니다. 이제 리본을 부분적으로 투명하게하여 일부 세부 사항이 혼합하지만 배경 위에 리본을 "동일한 색상"으로 유지합니다.

주어진 불투명도 / 알파가 리본 색상의 100 % 미만인 경우 배경 위에 100 % 불투명도를 가진 색상과 동일해야하는 RGB를 (쉽게) 가능한 수있는 방법이?

여기 사진이 있습니다. 배경은 rgb(72, 28, 97)리본 rgb(45, 34, 70)입니다. rgba(r, g, b, a)이 단색과 동일하게 보이도록 리본을 위해 원합니다 .

여기에 이미지 설명 입력


색상 혼합은 채널당 선형 보간입니다. 따라서 수학은 매우 간단합니다. RGB2보다 RGBA1이있는 경우 유용한 효과 결과 RGB3은 다음과 있습니다.

r3 = r2 + (r1-r2)*a1
g3 = g2 + (g1-g2)*a1
b3 = b2 + (b1-b2)*a1

… 알파 채널은 0.0에서 1.0까지입니다.

온 전성 검사 : 알파가 0이면 RGB3이 RGB2와 같습니까? 예. 알파가 1이면 RGB3이 RGB1과 같습니까? 예.

배경색과 최종 색상 만 잠근 경우 요구 사항을 충족 할 수있는 RGBA 색상 (무한, 부동 소수점 공간)이 많이 있습니다. 따라서 바의 색상이나 원하는 불투명도를 선택하고 다른 값을 찾아야합니다.

알파를 기반으로 색상 선택

RGB3 (마지막 원하는 색상), RGB2 (배경색) 및 A1 (원하는 불투명도)을 알고 있고 RGB1을 선호하는 방정식을 다시 정렬 할 수 있습니다.

r1 = (r3 - r2 + r2*a1)/a1
g1 = (g3 - g2 + g2*a1)/a1
b1 = (b3 - b2 + b2*a1)/a1

이론적으로는 가능하지만 표준 RGBA 범위에서는 불가능한 몇 가지 색상 조합이 있습니다. 예를 들어 배경이 순수한 검정이고 원하는 인식 색상이 순수한 흰색이고 원하는 알파가 1 %이면 다음이됩니다.

r1 = g1 = b1 = 255/0.01 = 25500

… 사용 가능한 어떤 것보다 100 배 더 밝은 매우 밝은 흰색.

색상을 기반으로 알파 선택

RGB3 (마지막 원하는 색상), RGB2 (배경색) 및 RGB1 (불투명도를 변경하려는 색상)을 알고 있고 A1을 찾고있는 경우 방정식 :

a1 = (r3-r2) / (r1-r2)
a1 = (g3-g2) / (g1-g2)
a1 = (b3-b2) / (b1-b2)

두 가지 다른 값을 제공하는 경우 정확히 일치 수는 없지만 가능한 한 가까워 지도록 알파의 평균을 낼 수 있습니다. 예를 들어, 파란색을 만들기 위해 빨간색 위에 녹색을 놓을 수있는 불투명도는 없습니다.


나는 Phrogz의 대답을 사용하여 약간 믹스 인을 만들었습니다. 당신은 입력 :

  1. 색상이 어떻게 보일까요
  2. 특정 알파로
  3. 주어진 배경에 (요법은 흰색)

코드는 다음과 가변적입니다.

.bg_alpha_calc (@desired_colour, @desired_alpha, @background_colour: white) {
    @r3: red(@desired_colour);
    @g3: green(@desired_colour);
    @b3: blue(@desired_colour);

    @r2: red(@background_colour);
    @g2: green(@background_colour);
    @b2: blue(@background_colour);

    // r1 = (r3 - r2 + r2 * a1) / a1
    @r1: ( @r3 - @r2 + (@r2 * @desired_alpha) ) / @desired_alpha;
    @g1: ( @g3 - @g2 + (@g2 * @desired_alpha) ) / @desired_alpha;
    @b1: ( @b3 - @b2 + (@b2 * @desired_alpha) ) / @desired_alpha;

    background-color: @desired_colour;
    background-color: rgba(@r1, @g1, @b1, @desired_alpha);

}

다음과 같은 사용법 :

@mycolour: #abc;
@another_colour: blue;
.box_overlay {
  // example:
  .bg_alpha_calc (@mycolour, 0.97, @another_colour);
  // or (for white bg) just:
  .bg_alpha_calc (@mycolour, 0.97);
}

분명히 불가능한 조합 (Phrogz에서 언급했듯이)에서는 작동하지 않습니다. 즉, 약간의 투명도 만 지원 의미입니다. 당신이 그것으로 어떻게 가는지.


Phrogzephemer 의 훌륭한 답변 덕분에 여기 에 추론 적합한 RGBA 개 색상 자동으로 계산 하는 SASS가 함수 있습니다.

원하는 색상과 기존 배경으로 호출하면 반올림 오류로 인해 RGB 구성 요소의 ± 1/256 이내에서 원하는 결과를 제공하는 최적화 (가장 투명 함을 의미)에 해당하는 RGBA 색상을 계산합니다.

@function alphaize($desired-color, $background-color) {

    $r1: red($background-color);
    $g1: green($background-color);
    $b1: blue($background-color);

    $r2: red($desired-color);
    $g2: green($desired-color);
    $b2: blue($desired-color);

    $alpha: 0;
    $r: -1;
    $g: -1;
    $b: -1;

    @while $alpha < 1 and ($r < 0 or $g < 0 or $b < 0
                           or $r > 255 or $g > 255 or $b > 255) {
        $alpha: $alpha + 1/256;
        $inv: 1 / $alpha;
        $r: $r2 * $inv + $r1 * (1 - $inv);
        $g: $g2 * $inv + $g1 * (1 - $inv);
        $b: $b2 * $inv + $b1 * (1 - $inv);
    }

    @return rgba($r, $g, $b, $alpha);
}

방금 여러 조합 (모든 Bootswatch 테마)에 대해 테스트 한 결과 dark-on-light 및 light-on-dark 결과 모두에서 효과가 있습니다.

추신 : 결과 색상에서 ± 1 / 256 이상의 정밀도가 필요한 경우 rgba 색상을 혼합 할 때 어떤 종류의 반올림 알고리즘 브라우저가 적용되는지 알고 있어야합니다 (표준화되었는지 여부는 모르겠습니다). 조건을 기존 @while에 추가 $alpha하여 원하는 정밀도에 도달 할 때까지 계속 증가 합니다.


@Phrogz의 대답에서 :

r3 = r2 + (r1-r2)*a1
g3 = g2 + (g1-g2)*a1
b3 = b2 + (b1-b2)*a1

그래서:

r3 - r2 = (r1-r2)*a1
g3 - g2 = (g1-g2)*a1
b3 - b2 = (b1-b2)*a1

그래서:

r1 = (r3 - r2) / a1 + r2
g1 = (g3 - g2) / a1 + g2
b1 = (b3 - b2) / a1 + b2

당신의 모든 값을 선택할 수 있습니다 a1, 이것은의 해당 값을 찾을 수 있습니다 r1, g1그리고 b1필요합니다. 예를 들어 알파 1을 선택하면 RGB1 = RGB3이 필요하지만 알파 0을 선택하면 솔루션이 제공되지 않습니다 (분명히).


@Tobia의 답변을 확장하고 더 투명하게 불투명도를 지정해야 다음을 수행하십시오.

@function rgbaMorph($desired-color, $background-color: rgb(255,255,255), $desired-alpha: 0) {

    $r1: red($desired-color);
    $g1: green($desired-color);
    $b1: blue($desired-color);

    $r2: red($background-color);
    $g2: green($background-color);
    $b2: blue($background-color);

    $r: -1;
    $g: -1;
    $b: -1;

    @if ($desired-alpha != 0) {
        $r: ( $r1 - $r2 + ($r2 * $desired-alpha) ) / $desired-alpha;
        $g: ( $g1 - $g2 + ($g2 * $desired-alpha) ) / $desired-alpha;
        $b: ( $b1 - $b2 + ($b2 * $desired-alpha) ) / $desired-alpha;
    }

    @if (($desired-alpha == 0) or ($r < 0 or $g < 0 or $b < 0
                           or $r > 255 or $g > 255 or $b > 255)) {
        //if alpha not attainable, this will find lowest alpha that is

        $alpha: $desired-alpha;
        @while $alpha < 1 and ($r < 0 or $g < 0 or $b < 0
                           or $r > 255 or $g > 255 or $b > 255) {
            $alpha: $alpha + 1/256;
            $inv: 1 / $alpha;
            $r: $r1 * $inv + $r2 * (1 - $inv);
            $g: $g1 * $inv + $g2 * (1 - $inv);
            $b: $b1 * $inv + $b2 * (1 - $inv);
        }
        @debug "Color not attainable at opacity using alpha: " $alpha " instead of: " $desired-alpha;

        $desired-alpha: $alpha;
    }

    @return rgba($r, $g, $b, $desired-alpha);
}

참고 URL : https://stackoverflow.com/questions/12228548/finding-equivalent-color-with-opacity

반응형