Eu tenho uma cor hexadecimal, por exemplo, #F4F8FB
(ou rgb(244, 248, 251)
) que desejo converter em uma cor rgba o mais transparente possível (quando exibida em branco). Faz sentido? Estou procurando um algoritmo, ou pelo menos a idéia de um algoritmo para saber como fazê-lo.
Por exemplo:
rgb( 128, 128, 255 ) --> rgba( 0, 0, 255, .5 )
rgb( 152, 177, 202 ) --> rgba( 50, 100, 150, .5 ) // can be better(lower alpha)
Ideias?
Solução FYI baseada na resposta 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
fonte
fonte
Respostas:
Pegue o componente de cor mais baixo e converta-o em um valor alfa. Em seguida, redimensione os componentes de cor subtraindo o menor e dividindo pelo valor alfa.
Exemplo:
Então,
rgb(152, 177, 202)
exibe comorgba(0, 62, 123, .404)
.Eu verifiquei no Photoshop que as cores realmente combinam perfeitamente.
fonte
.404
), mas não conseguia entender os números.0..255
para0..1
e invertendo. Usar1.0 - 152 / 255
também funcionaria. Convertendo os componentes de cor é simplesmente escalar a partirn..255
de0..255
onden
é o menor componente.Seja r, g e b os valores de entrada e r ', g', b 'e a' sejam os valores de saída, todos redimensionados (por enquanto, pois torna a matemática mais bonita) entre 1 e 0. Então, por a fórmula para sobrepor cores:
Os termos 1 - a 'representam a contribuição em segundo plano e os outros termos representam o primeiro plano. Faça alguma álgebra:
Intuitivamente, parece que o valor mínimo da cor será o fator limitante do problema, portanto, ligue-o a m:
Defina o valor de saída correspondente, m ', como zero, pois queremos maximizar a transparência:
Então, em javascript (traduzindo de 1 para 255 ao longo do caminho):
Note que estou assumindo que a 'é opacidade aqui. É trivial alterá-lo para transparência - basta remover o "1 -" da fórmula para a '. Outra coisa a se notar é que isso não parece produzir resultados exatos - dizia que a opacidade era de 0,498 para o exemplo que você deu acima (128, 128, 255). No entanto, isso é extremamente próximo.
fonte
[255 * (r/255 - 1) / a + 1 * 255, ...] == [(255*r/255 - 255 * 1) / a + 255, ...] == [(r - 255) / a + 255, ...]
Gostaria de olhar para RGB <-> HSL conversão. Ou seja, luminosidade == quantidade de branco == quantidade de transparência.
Para o seu exemplo
rgb( 128, 128, 255 )
, precisamos alterar os valores RGB para o0
primeiro pela quantidade máxima, ou seja, parargb( 0, 0, 128 )
- essa seria a nossa cor com o mínimo de branco possível. Depois disso, usando a fórmula da luminância, calculamos a quantidade de branco que precisamos adicionar à nossa cor escura para obter a cor original - esse seria o nosso alfa:Espero que isso faça sentido. :)
fonte
Para aqueles que usam SASS / SCSS, escrevi uma pequena função SCSS para que você possa usar facilmente o algoritmo descrito por @Guffa
fonte
Estou apenas descrevendo uma idéia para o algoritmo, sem solução completa:
Basicamente, você tem três números
x
,y
,z
e está à procura de três novos númerosx'
,y'
,z'
e um multiplicadora
na faixa [0,1] de tal forma que:Isso está escrito em unidades em que os canais também recebem valores no intervalo [0,1]. Em valores discretos de 8 bits, seria algo como isto:
Além disso, você deseja o maior valor possível
a
. Você pode resolver:Etc. Em valores reais, existem infinitas soluções, basta conectar qualquer número real
a
, mas o problema é encontrar um número para o qual o erro de discretização é mínimo.fonte
Isso deve servir:
fonte
y
e(y-x)
. O255 / (y-x)
incorretamente força o maior número para255
, então você sempre acabar com um único0
, um único255
e, em seguida, outro número:0, 22, 255
,255, 0, 55
, etc .../a
e, em seguida, corresponde à resposta correta.A resposta principal não funcionou para mim com componentes de baixa cor. Por exemplo, ele não calcula o alfa correto se a cor for # 80000. Tecnicamente, ele deve ser convertido em # ff0000 com alfa 0.5. Para resolver isso, você precisa usar a conversão RGB -> HSL -> RGBA. Este é um pseudocódigo para obter os valores corretos:
"newRgb" conterá o valor da nova cor ajustada e usará a variável "alpha" para controlar a transparência.
fonte
#800000
ergba( 255, 0, 0, .5 )
não estão nem perto da mesma cor. O primeiro seria vermelho escuro, o segundo salmão-ish. A menos que seja exibido sobre preto, acho que serão os mesmos.