अस्पष्टता के साथ "समकक्ष" रंग ढूँढना


92

मान लें कि मेरे पास "रिबन" के साथ एक पृष्ठभूमि रंग है, जो दूसरे ठोस रंग में चल रहा है। अब, मैं चाहता हूं कि कुछ विवरणों को मिश्रण करने के लिए रिबन आंशिक रूप से पारदर्शी हो, लेकिन फिर भी पृष्ठभूमि पर रिबन को "समान रंग" रखें।

क्या कोई आसानी से (आसानी से) निर्धारित तरीका है, किसी दिए गए अपारदर्शिता / अल्फा <100% रिबन रंग के लिए, पृष्ठभूमि पर 100% अस्पष्टता के साथ इसके रंग के समान आरजीबी मान क्या होना चाहिए?

यहाँ एक तस्वीर है। बैकग्राउंड है rgb(72, 28, 97), रिबन है rgb(45, 34, 70)। मैं rgba(r, g, b, a)रिबन के लिए चाहता हूं ताकि यह इस ठोस रंग के समान दिखाई दे।

यहां छवि विवरण दर्ज करें


1
एक बहुत ही समान प्रश्न यहां पाया जा सकता है: stackoverflow.com/questions/6672374/convert-rgb-rgba लेकिन महत्वपूर्ण अंतर यह है कि यह प्रश्न सफेद रंग के आधार रंग को निर्दिष्ट करता है, जबकि यह एक मनमाना है।
— BoltClock

जवाबों:


129

रंग सम्मिश्रण प्रति चैनल सिर्फ एक रैखिक प्रक्षेप है, है ना? तो गणित बहुत सरल है। यदि आपके पास RGB2 RGB2 से अधिक है, तो प्रभावी दृश्य परिणाम RGB3 होगा:

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

... जहाँ अल्फा चैनल 0.0 से 1.0 तक है।

Sanity check: यदि अल्फा 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)

यदि ये अलग-अलग मान देते हैं, तो आप इसे ठीक से मेल नहीं खा सकते हैं, लेकिन जितना संभव हो उतना करीब पाने के लिए आप अल्फाजों को औसत कर सकते हैं। उदाहरण के लिए, दुनिया में कोई अपारदर्शिता नहीं है जो आपको नीला पाने के लिए लाल रंग में हरा डाल देगा।


नहीं कर रहे हैं r1, g1और b1भी अज्ञात?
— एरिक

@ मैं निश्चित नहीं हूँ। मैंने उत्तर को संपादित किया है यदि यह अल्फा स्तर है जो ज्ञात है और जो रंग नहीं हैं।
— फ्रॉग्ज

शीर्ष पर, मैंने फ़ोटोशॉप में अपने पहले तीन फ़ार्मुलों का उपयोग किया था ताकि यह पता लगाया जा सके कि एक रंग 0.8 अल्फा पर होगा जब मेरा एकमात्र अन्य संदर्भ रंग सफेद था ... मुझे खोजने के लिए 1 + (1 - a) या 1.2 का उपयोग करना था। सही रंग ...
— जॉन विलियम डोमिंगो

1
@ फ्रॉग मैं आपके 'पिक द कलर पर आधारित अल्फा' समीकरणों का उपयोग कर रहा हूं, और मुझे लाल चैनल के लिए एक नकारात्मक संख्या (-31) मिली है। जब मैं ऋणात्मक को लाल मान के रूप में उपयोग करता हूं, तो मुझे वही परिणाम मिलता है जैसे मैंने लाल मूल्य के रूप में 0 का उपयोग किया था। क्या इस नकारात्मक को किसी उपयोगी वस्तु में बदलने का कोई तरीका है? यहाँ क्या हो रहा है के रूप में कोई सुराग?
— रात्रि

हो सकता है कि मेरी गणना बंद हो, लेकिन यह सूत्र RGB3 = # 163920, RGB2 = #FFFFFF, और A1 = 0.92 जब अप्रत्याशित परिणाम उत्पन्न करता है; परिकलित RGB1 = rgb (2, 40, 13), लेकिन rgba (2, 40, 13, 0.92) = # 15381F, # 163920 नहीं।
— ३

12

मैंने फ्रॉगज़ के उत्तर का उपयोग करके एक कम मिश्रण बनाया। आप इनपुट:

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

स्पष्ट रूप से असंभव संयोजनों के लिए काम नहीं करता है (जैसा कि फ्रॉग्ज द्वारा उल्लेख किया गया है), इसका मतलब है कि पारदर्शिता के केवल हल्के स्तर का समर्थन किया जाता है। देखें कि आप इसके साथ कैसे जाते हैं।


1
@mixin bg_alpha_calc ($ इच्छित_ रंग, $ वांछित_पाल, $ पृष्ठभूमि_ रंग: सफेद) {$ r3: लाल ($ वांछित_ रंग); $ g3: हरा ($ वांछित_ रंग); $ b3: नीला ($ इच्छित_ रंग); $ r2: लाल ($ पृष्ठभूमि_ रंग); $ g2: हरा ($ पृष्ठभूमि_ रंग); $ b2: नीला ($ पृष्ठभूमि_ रंग); // r1 = (r3 - r2 + r2 * a1) / a1 $ r1: ($ r3 - $ r2 + ($ r2 * $ वांछित_आलफा)) / $ वांछित_आलफा; $ g1: ($ g3 - $ g2 + ($ g2 * $ वांछित_ल्पा)) / $ वांछित_लघु; $ b1: ($ b3 - $ b2 + ($ b2 * $ वांछित_ल्पा)) / $ वांछित_लघु; पृष्ठभूमि-रंग: $ वांछित_ रंग; पृष्ठभूमि-रंग: rgba ($ r1, $ g1, $ b1, $ वांछित_ल्पा); }
— मेटाकॉलिन जूल

2
मैंने एससीएसएस संस्करण मिक्सिन अपनाया और बनाया। यहां डेमो और कोड खोजें: codepen.io/Grienauer/pen/Grogdx
— Grienauer

@Grienauer मैंने ठीक वैसा ही किया, एहसास नहीं हुआ कि आपने इसे पहले ही साझा कर लिया है! मेरा एकमात्र अंतर यह है कि मैंने पृष्ठभूमि के रंग को सफेद कर दिया
— तेहलवी

7

के लिए धन्यवाद Phrogz की और ephemer के महान जवाब, यहाँ एक एस.ए.एस.एस. समारोह है कि है स्वतः सबसे अच्छा बराबर RGBA रंग गणना करता है।

आप इसे वांछित रंग और मौजूदा पृष्ठभूमि के साथ कहते हैं, और यह सर्वोत्तम (मतलब सबसे पारदर्शी) समकक्ष RGBA रंग की गणना करेगा जो प्रत्येक RGB घटक के 256 1/256 के भीतर वांछित परिणाम देता है (गोलाई त्रुटियों के कारण):

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

मैंने इसे कई संयोजनों (सभी बूटस्वाच थीम) के खिलाफ परीक्षण किया और यह अंधेरे-पर-प्रकाश और हल्के-से-अंधेरे परिणामों के लिए एक उपचार का काम करता है।

पुनश्च: यदि आपको परिणामी रंग में / 1/256 परिशुद्धता से बेहतर चाहिए, तो आपको यह जानना होगा कि आरजीबीए रंग सम्मिश्रण करते समय किस प्रकार के गोपन एल्गोरिथ्म लागू होते हैं (मुझे नहीं पता कि यह मानकीकृत है या नहीं) और एक उपयुक्त जोड़ें मौजूदा स्थिति @while, ताकि यह $alphaतब तक बढ़ती रहे जब तक कि यह वांछित सटीकता प्राप्त न कर ले।


2
FYI करें, इस समारोह के रूप में स्टाइलस में मौजूद है transparentify(): stylus-lang.com/docs/bifs.html#transparentifytop-bottom-alpha ... जो मैं स्टाइलस के लिए मैन्युअल रूप से इस पोर्टिंग के बाद पता चला ...
— weotch

6

@ फ्रॉग के जवाब से:

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 का अल्फा चुनना कोई समाधान नहीं देता है (स्पष्ट रूप से)।


1

सबसे व्यावहारिक समाधान जो मैंने अब तक पाया: बस एक रंग बीनने वाले उपकरण के साथ परिणामी रंग को मापें और फिर ओवरले के लिए मापा रंग का उपयोग करें। यह विधि एक सही रंग मैच देती है।

मैंने विभिन्न मिश्रणों का उपयोग करने की कोशिश की है, लेकिन गोलाई त्रुटि के कारण, मैं अभी भी नग्न आंखों से अंतर देख पा रहा था


1
ओपी शायद दृढ़ संकल्प को गतिशील बनाने का एक तरीका चाहता था, लेकिन यह विशेष रूप से नहीं कहा गया था, और आपका जवाब स्थिर रंग / अल्फा चयन के लिए एक अच्छा हैक देता है।
— एरिक नोल्स

0

@ टोबिया के उत्तर पर विस्तार करने के लिए और अस्पष्टता को अधिक स्पष्ट करने के लिए पारदर्शी की तरह अनुमति दें:

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