Convertir RGB a RGBA sobre blanco

Resuelto asked hace 13 años • 7 respuestas

Tengo un color hexadecimal, por ejemplo #F4F8FB(o rgb(244, 248, 251)) que quiero convertir en un color lo más transparente posible (cuando se muestra sobre blanco). ¿Tener sentido? Estoy buscando un algoritmo, o al menos una idea de un algoritmo sobre cómo hacerlo.

Por ejemplo:

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

¿Ideas?


Solución para su información basada en la respuesta de Guffa:

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)' 
    }
 avatar Jul 13 '11 06:07
Aceptado

Tome el componente de color más bajo y conviértalo a un valor alfa. Luego escale los componentes de color restando el más bajo y dividiéndolo por el valor alfa.

Ejemplo:

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

Entonces, rgb(152, 177, 202)se muestra como rgba(0, 62, 123, .404).

He verificado en Photoshop que los colores realmente combinan perfectamente.

Guffa avatar Jul 12 '2011 23:07 Guffa

Sean r, g y b los valores de entrada y r', g', b' y a' los valores de salida, todos escalados (por ahora, ya que hace las matemáticas más bonitas) entre 1 y 0. Luego, por la fórmula para superponer colores:

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

Los términos 1 - a' representan la contribución de fondo y los demás términos representan el primer plano. Haz algo de álgebra:

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

Intuitivamente, parece que el valor mínimo de color será el factor limitante en el problema, así que vincule esto a m:

m = min(r, g, b)

Establezca el valor de salida correspondiente, m', en cero, ya que queremos maximizar la transparencia:

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

Entonces, en javascript (traduciendo del 1 al 255 en el camino):

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

Tenga en cuenta que asumo que a' es opacidad aquí. Es trivial cambiarlo a transparencia; simplemente elimine el "1 -" de la fórmula para a'. Algo a tener en cuenta es que esto no parece producir resultados exactos: decía que la opacidad era 0,498 para el ejemplo que proporcionó anteriormente (128, 128, 255). Sin embargo, esto está muy cerca.

gereeter avatar Jul 13 '2011 00:07 gereeter

Buscaría la conversión RGB<->HSL. Es decir, luminosidad == cantidad de blanco == cantidad de transparencia.

Para su ejemplo rgb( 128, 128, 255 ), necesitamos cambiar los valores RGB al 0primero en la cantidad máxima, es decir rgb( 0, 0, 128 ), ese sería nuestro color con la menor cantidad de blanco posible. Y después de eso, usando la fórmula para la luminancia, calculamos la cantidad de blanco que necesitamos agregar a nuestro color oscuro para obtener el color original; ese sería nuestro alfa:

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;

Espero que tenga sentido. :)

lxa avatar Jul 12 '2011 23:07 lxa