Tengo un color hexadecimal, por ejemplo #F4F8FB
(o rgb(244, 248, 251)
) que quiero convertir en un color rgba tan transparente como sea posible (cuando se muestra en 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)'
}
javascript
colors
css
rgba
Mark Kahn
fuente
fuente
Respuestas:
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 dividiendo por el valor alfa.
Ejemplo:
Entonces, se
rgb(152, 177, 202)
muestra comorgba(0, 62, 123, .404)
.Verifiqué en Photoshop que los colores realmente coinciden perfectamente.
fuente
.404
) pero no pude conseguir que los números funcionen.0..255
a0..1
e invertir. Usar1.0 - 152 / 255
también funcionaría. La conversión de los componentes de color es simplemente escalando a partirn..255
de0..255
donden
es el componente más bajo.Sean r, g y b los valores de entrada y r ', g', b 'y a' sean los valores de salida, todos escalados (por ahora, ya que hace que las matemáticas sean más bonitas) entre 1 y 0. Luego, por La fórmula para superponer colores:
Los términos 1 - a 'representan la contribución de fondo, y los otros términos representan el primer plano. Haz algo de álgebra:
Intuitivamente, parece que el valor mínimo de color será el factor limitante en el problema, por lo que debe asociarlo a m:
Establezca el valor de salida correspondiente, m ', en cero, ya que queremos maximizar la transparencia:
Entonces, en javascript (traduciendo de 1 a 255 en el camino):
Tenga en cuenta que estoy asumiendo que a 'es opacidad aquí. Es trivial cambiarlo a transparencia: simplemente elimine el "1 -" de la fórmula para un '. Otra cosa a tener en cuenta es que esto no parece producir resultados exactos: dice que la opacidad fue de 0.498 para el ejemplo que proporcionó anteriormente (128, 128, 255). Sin embargo, esto está extremadamente cerca.
fuente
[255 * (r/255 - 1) / a + 1 * 255, ...] == [(255*r/255 - 255 * 1) / a + 255, ...] == [(r - 255) / a + 255, ...]
Me gustaría ver la conversión RGB <-> HSL. Es decir, luminosidad == cantidad de blanco == cantidad de transparencia.
Para su ejemplo
rgb( 128, 128, 255 )
, necesitamos cambiar0
primero los valores RGB a la cantidad máxima, es decir, argb( 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:Espero que tenga sentido. :)
fuente
Para aquellos de ustedes que usan SASS / SCSS, he escrito una pequeña función SCSS para que puedan usar fácilmente el algoritmo descrito por @Guffa
fuente
Solo estoy describiendo una idea para el algoritmo, no hay una solución completa:
Básicamente, usted tiene tres números
x
,y
,z
y que busca tres nuevos númerosx'
,y'
,z'
y un multiplicadora
en el rango [0,1] tal que:Esto se escribe en unidades donde los canales también toman valores en el rango [0,1]. En valores discretos de 8 bits, sería algo como esto:
Además, desea el mayor valor posible
a
. Puedes resolver:Etc. En valores reales esto tiene infinitas soluciones, simplemente conecte cualquier número real
a
, pero el problema es encontrar un número para el cual el error de discretización sea mínimo.fuente
Esto debería hacerlo:
fuente
y
y(y-x)
. La255 / (y-x)
obliga incorrectamente el número más grande de255
, por lo que siempre iba a terminar con una sola0
, una sola255
y luego otro número:0, 22, 255
,255, 0, 55
, etc .../a
y luego coincidir con la respuesta correcta.La respuesta principal no me funcionó con componentes de bajo color. Por ejemplo, no calcula el alfa correcto si el color es # 80000. Técnicamente, debería convertirse en # ff0000 con alpha 0.5. Para resolver esto, debe usar la conversión RGB -> HSL -> RGBA. Este es un pseudocódigo para obtener los valores correctos:
"newRgb" contendrá el valor del nuevo color ajustado y usará la variable "alfa" para controlar la transparencia.
fuente
#800000
yrgba( 255, 0, 0, .5 )
no están cerca del mismo color. El primero sería rojo oscuro, el segundo salmón. A menos que se muestre en negro, creo que serían lo mismo.