सफेद पर RGB को RGBA में बदलें


196

मेरे पास एक हेक्स रंग है, उदाहरण के लिए #F4F8FB(या rgb(244, 248, 251)) जिसे मैं एक पारदर्शी-के रूप में संभव rgba रंग में परिवर्तित करना चाहता हूं (जब सफेद पर प्रदर्शित किया जाता है)। सही बात? मैं एक एल्गोरिथ्म की तलाश कर रहा हूं, या कम से कम एल्गोरिदम के बारे में सोचता हूं कि यह कैसे करना है।

उदाहरण के लिए:

rgb( 128, 128, 255 ) --> rgba(   0,   0, 255,  .5 )
rgb( 152, 177, 202 ) --> rgba(  50, 100, 150,  .5 ) // can be better(lower alpha)

विचार?


गुफ़ा के जवाब पर आधारित FYI समाधान:

function RGBtoRGBA(r, g, b){
    if((g == null) && (typeof r === 'string')){
        var hex = r.replace(/^\s*#|\s*$/g, '');
        if(hex.length === 3){
            hex = hex.replace(/(.)/g, '$1$1');
        }
        r = parseInt(hex.substr(0, 2), 16);
        g = parseInt(hex.substr(2, 2), 16);
        b = parseInt(hex.substr(4, 2), 16);
    }

    var min, a = (255 - (min = Math.min(r, g, b))) / 255;

    return {
        r    : r = 0|(r - min) / a,
        g    : g = 0|(g - min) / a,
        b    : b = 0|(b - min) / a,
        a    : a = (0|1000*a)/1000,
        rgba : 'rgba(' + r + ', ' + g + ', ' + b + ', ' + a + ')'
    };
}

RGBtoRGBA(204, 153, 102) == RGBtoRGBA('#CC9966') == RGBtoRGBA('C96') == 
    {
       r    : 170,
       g    : 85 ,
       b    : 0  ,
       a    : 0.6,
       rgba : 'rgba(170, 85, 0, 0.6)' 
    }

Interseting! आप अभी भी चाहते हैं कि यह सही दिखाई दे, न कि पूरी तरह से पारदर्शी?
मृकफ जूल 12'11

6
दिलचस्प सवाल! वहाँ कम से एक सटीक विपरीत सवाल है stackoverflow.com/questions/2049230/convert-rgba-color-to-rgb , यह मदद कर सकता है
apscience

@ मेरीच - हां, मैं चाहती हूं कि रंग सफेद होने पर समान दिखे, लेकिन जितना संभव हो उतना पारदर्शी हो।
मार्क कान

1
महान सवाल, मैं हमेशा सोचता हूं कि यह कैसे करना है, लेकिन आमतौर पर इससे दूर हो जाता है;) +1
डोमिनिक के

1
@ e100 - यह ट्रिगर करने वाला विशिष्ट प्रश्न stackoverflow.com/questions/6658350/… था । मूल रूप से मैं सब कुछ के ऊपर एक छाया तत्व डालकर क्लिक-थ्रू अवरुद्ध किए बिना पृष्ठभूमि-रंग के साथ तत्वों के शीर्ष पर सीएसएस छाया को ओवरले करने में सक्षम होना चाहता था। मैं भी कुछ समय के लिए ऐसा करना चाहता हूं ताकि मैं यादृच्छिक चीजें कर सकूं जैसे: jsfiddle.net/qwySW/2 । इसके अलावा मुझे यह एक आकर्षक सवाल लग रहा था :)
मार्क कहन

जवाबों:


185

सबसे कम रंग घटक लें, और इसे एक अल्फा मान में बदलें। फिर सबसे कम घटाकर और अल्फा मान से विभाजित करके रंग घटकों को स्केल करें।

उदाहरण:

152 converts to an alpha value of (255 - 152) / 255 ~ 0.404

152 scales using (152 - 152) / 0.404 = 0
177 scales using (177 - 152) / 0.404 ~ 62
202 scales using (202 - 152) / 0.404 ~ 123

तो, के rgb(152, 177, 202)रूप में प्रदर्शित करता है rgba(0, 62, 123, .404)

मैंने फ़ोटोशॉप में सत्यापित किया है कि रंग वास्तव में पूरी तरह से मेल खाते हैं।


1
धन्यवाद! मैं भी कुछ ऐसा ही कर रहा था (जैसे मिलता है .404), लेकिन काफी संख्या में काम नहीं कर पाया।
मार्क कान

3
FYI करें, प्रश्न में आपके उत्तर के आधार पर अंतिम समाधान पोस्ट किया गया
मार्क काह्न

2
@templatetypedef: te का सबसे निचला घटक अल्फा में परिवर्तित करना सीमा 0..255से लेकर 0..1और inverting तक स्केलिंग है । उपयोग 1.0 - 152 / 255करने से भी काम होगा। रंग घटकों को परिवर्तित करना केवल सबसे कम घटक है जहां से स्केलिंग n..255करना है। 0..255n
गुफा

1
@ क्रिसटोफ: सिद्धांत समान होगा, लेकिन अधिक जटिल। अल्फा की गणना करने के लिए केवल सबसे कम घटक का उपयोग करने के बजाय, आप प्रत्येक घटक के लिए सबसे कम संभव अल्फा की गणना करेंगे (अर्थात क्या अल्फा मान का उपयोग सही रंग पाने के लिए किया जाता है जब घटक मूल्य के रूप में 0 या 255 का उपयोग करते हुए), तो उच्चतम का उपयोग करें उन अल्फा वैल्यूज की। उस से आप गणना कर सकते हैं कि सही रंग प्राप्त करने के लिए उस अल्फा मान के साथ प्रत्येक घटक के लिए किस रंग मूल्य का उपयोग करें। ध्यान दें कि कुछ रंग संयोजन (उदाहरण के लिए काली पृष्ठभूमि पर सफेद) 1.0 सबसे कम संभव अल्फा मान के रूप में उपयोग करने के लिए देंगे।
गुफा

2
मैंने एक छोटी सी बेला लिखी जो इस समाधान को लागू करती है। लिंक यहां दिया गया है। jsfiddle.net/wb5fwLoc/1 । हो सकता है कि आप में से कोई इसका उपयोग कर सकता है। यह सिर्फ एक त्वरित, बग-मुक्त स्क्रिप्ट नहीं है .. यह चारों ओर खेलने के लिए पर्याप्त होना चाहिए।
च्समयैन

23

1 और 0. के बीच r, g, और b इनपुट वैल्यू हो और r ', g', b ', और' a आउटपुट आउटपुट वैल्यू हो, सभी स्केल किए गए (अभी के लिए गणित को पूर्ववर्ती बनाता है)। रंग ओवरले करने का सूत्र:

r = a' * r' + 1 - a'
g = a' * g' + 1 - a'
b = a' * b' + 1 - a'

1 - 'ए' शब्द पृष्ठभूमि योगदान का प्रतिनिधित्व करते हैं, और अन्य शब्द अग्रभूमि का प्रतिनिधित्व करते हैं। कुछ बीजगणित करें:

r = a' * (r' - 1) + 1
r - 1 = a' * (r' - 1)
(r - 1) / (r' - 1) = a'
(r' - 1) / (r - 1) = 1 / a'
r' - 1 = (r - 1) / a'
r' = (r - 1) / a' + 1

सहज रूप से, ऐसा लगता है कि न्यूनतम रंग मूल्य समस्या में सीमित कारक होगा, इसलिए इसे मी से बांधें:

m = min(r, g, b)

जैसा कि हम पारदर्शिता को अधिकतम करना चाहते हैं, वैसा ही आउटपुट मूल्य, m 'को शून्य पर सेट करें:

0 = (m - 1) / a' + 1
-1 = (m - 1) / a'
-a' = m - 1
a' = 1 - m

तो, जावास्क्रिप्ट में (रास्ते में 1 से 255 तक अनुवाद):

function rgba(r, g, b) {
    var a = 1 - Math.min(r, Math.min(g, b)) / 255;
    return [255 + (r - 255) / a, 255 + (g - 255) / a, 255 + (b - 255) / a, a];
}

ध्यान दें कि मैं मान रहा हूँ कि 'यहाँ अस्पष्टता है। इसे पारदर्शिता में बदलना तुच्छ है - बस '1 -' को 'एक' के लिए सूत्र से हटा दें। ध्यान देने वाली बात यह है कि यह सटीक परिणाम नहीं देता है - यह कहा गया कि आपके द्वारा दिए गए उदाहरण के लिए अपारदर्शिता 0.498 थी (128, 128, 255)। हालांकि, यह बेहद करीब है।


यदि आप अपने समीकरण में गुणा 255 का वितरण करते हैं, तो आपको सही परिणाम मिलता है -[255 * (r/255 - 1) / a + 1 * 255, ...] == [(255*r/255 - 255 * 1) / a + 255, ...] == [(r - 255) / a + 255, ...]
गेरेटर

6

मैं RGB <-> HSL रूपांतरण देखना चाहता हूँ। यानी चमकदारता == सफेद की मात्रा == पारदर्शिता की मात्रा।

आपके उदाहरण के लिए rgb( 128, 128, 255 ), हमें RGB मानों को 0पहली बार अधिकतम राशि से स्थानांतरित rgb( 0, 0, 128 )करना होगा , अर्थात - हमारा रंग जितना संभव हो उतना कम सफेद होगा। और उसके बाद, ल्यूमिनेन्स के लिए सूत्र का उपयोग करते हुए, हम मूल रंग प्राप्त करने के लिए हमारे काले रंग को जोड़ने के लिए सफेद की मात्रा की गणना करते हैं - जो कि हमारा अल्फा होगा:

L = (MAX(R,G,B) + MIN(R,G,B))/2
L1 = (255 + 128) / 2 = 191.5
L2 = (128 + 0) /2 = 64
A = (191,5 - 64) / 255 = 0,5;

आशा है कि समझ में आता है। :)


6

SASS / SCSS का उपयोग करने वालों में से, मैंने एक छोटा सा SCSS फ़ंक्शन लिखा है, ताकि आप @Guffa द्वारा वर्णित एल्गोरिदम का आसानी से उपयोग कर सकें

@function transparentize-on-white($color)
{
    $red: red($color);
    $green: green($color);
    $blue: blue($color);
    $lowestColorComponent: min($red, $green, $blue);
    $alpha: (255 - $lowestColorComponent) / 255;

    @return rgba(
        ($red - $lowestColorComponent) / $alpha,
        ($green - $lowestColorComponent) / $alpha,
        ($blue - $lowestColorComponent) / $alpha,
        $alpha
    );
}

3

मैं एल्गोरिथ्म के लिए एक विचार का वर्णन कर रहा हूं, कोई पूर्ण समाधान नहीं:

असल में, आप तीन नंबर हैं x, y, zऔर आप तीन नए नंबरों के लिए देख रहे हैं x', y', z'और एक गुणक aरेंज में [0,1] ऐसी है कि:

x = a + (1 - a) x'
y = a + (1 - a) y'
z = a + (1 - a) z'

यह उन इकाइयों में लिखा जाता है जहाँ चैनल रेंज [0,1] में मान भी लेते हैं। 8bit असतत मूल्यों में, यह कुछ इस तरह होगा:

x = 255 a + (1 - a) x'
y = 255 a + (1 - a) y'
z = 255 a + (1 - a) z'

इसके अलावा, आप सबसे बड़ा संभव मूल्य चाहते हैं a। आप हल कर सकते हैं:

a  = (x - x')/(255 - x')          x' = (x - 255 a)/(1 - a)

आदि वास्तविक मूल्यों में यह असीम रूप से कई समाधान हैं, बस किसी भी वास्तविक संख्या में प्लग करें a, लेकिन समस्या एक संख्या खोजने के लिए है जिसके लिए विवेकाधीन त्रुटि न्यूनतम है।


0

यह करना चाहिए:

let x = min(r,g,b)
a = 1 - x/255                    # Correction 1
r,g,b = ( (r,g,b) - x ) / a      # Correction 2

मैंने वास्तव में सिर्फ यह देखा कि मुझे अल्फा कैल्क (अभी तय) में एक त्रुटि थी। ताकि इसके साथ भी कुछ हो सकता है।
सच्चाई

अभी भी आपके yऔर द्वारा शुरू की गई एक समस्या है (y-x)255 / (y-x)गलत तरीके से करने के लिए सबसे बड़ी संख्या मजबूर करता 255है, तो आप हमेशा एक ही पहुंचते हैं 0, एक एकल 255और फिर एक और नंबर: 0, 22, 255, 255, 0, 55, आदि ...
मार्क क्हान

मैं देखता हूं, इसलिए यह गहरे रंगों की अनुमति नहीं देगा ... मुझे इसे बनाना चाहिए /aऔर फिर यह सही उत्तर से मेल खाता है।
सच्चाई १३:११

-1

शीर्ष उत्तर मेरे लिए निम्न रंग घटकों के साथ काम नहीं करता था। उदाहरण के लिए यह सही अल्फा की गणना नहीं करता है यदि रंग # 80000 है। तकनीकी रूप से इसे अल्फा 0.5 के साथ # ff0000 में बनाना चाहिए। इसे हल करने के लिए, आपको RGB -> HSL -> RGBA रूपांतरण का उपयोग करने की आवश्यकता है। सही मान प्राप्त करने के लिए यह छद्म कोड है:

//Convert RGB to HSL
hsl = new HSL(rgb)

//Use lightness as alpha
alpha = hsl.Lightness

//For #80000 lightness is 0.5, so we have to take this into account.
//Lightness more than 0.5 converts to alpha 1 and below is a linear ratio
if (alpha > 0.5)
{
    alpha = 1;
}
else
{
    alpha = alpha / 0.5;
    //We need to drop the lightness of the color to 0.5 to get the actual color
    //that needs to display. Alpha blending will take care of that.
    hsl.Lightness = 0.5;
}

newRgb = hsl.convertToRgb()

"newRgb" में नए समायोजित रंग का मान होगा और पारदर्शिता को नियंत्रित करने के लिए "अल्फा" चर का उपयोग किया जाएगा।


#800000और rgba( 255, 0, 0, .5 )कहीं भी उसी रंग के पास नहीं हैं। पहला गहरा लाल होगा, दूसरा सामन-ईश। जब तक काले रंग का प्रदर्शन नहीं होता है, तब मुझे लगता है कि वे समान होंगे।
मार्क कहन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.