100 votes

Trouver une couleur "équivalente" avec l'opacité

Disons que j'ai une couleur de fond sur laquelle se trouve un "ruban" d'une autre couleur unie. Je souhaite que le ruban soit partiellement transparent pour laisser transparaître certains détails, tout en conservant la "même couleur" sur le fond.

Existe-t-il un moyen de déterminer (facilement), pour une opacité/alpha donnée < 100% de la couleur du ruban, quelles valeurs RVB il devrait avoir pour être identique à sa couleur avec une opacité de 100% sur le fond ?

Voici une photo. L'arrière-plan est rgb(72, 28, 97) , ruban rgb(45, 34, 70) . Je veux un rgba(r, g, b, a) pour le ruban afin qu'il apparaisse identique à cette couleur unie.

enter image description here

137voto

Phrogz Points 112337

Le mélange des couleurs est juste une interpolation linéaire par canal, non ? Le calcul est donc assez simple. Si vous avez RGBA1 sur RGB2, le résultat visuel effectif RGB3 sera :

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

où le canal alpha est compris entre 0,0 et 1,0.

Contrôle de bon sens : si l'alpha est égal à 0, RGB3 est-il identique à RGB2 ? Oui. Si l'alpha est 1, RGB3 est-il identique à RGB1 ? Oui.

Si vous ne verrouillez que la couleur d'arrière-plan et la couleur finale, il existe un grand nombre de couleurs RGBA (infinies, dans l'espace à virgule flottante) qui pourraient répondre aux exigences. Vous devez donc choisir soit la couleur de la barre, soit le niveau d'opacité que vous souhaitez, et trouver la valeur de l'autre.

Choisir la couleur en fonction de l'alpha

Si vous connaissez RVB3 (la couleur finale souhaitée), RVB2 (la couleur d'arrière-plan) et A1 (le degré d'opacité souhaité), et que vous cherchez uniquement RVB1, nous pouvons réorganiser les équations de la manière suivante :

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

Il existe certaines combinaisons de couleurs qui sont théoriquement possibles, mais impossibles compte tenu de la gamme standard RGBA. Par exemple, si l'arrière-plan est noir pur, que la couleur perçue souhaitée est blanc pur et que l'alpha souhaité est de 1 %, vous aurez besoin de :

r1 = g1 = b1 = 255/0.01 = 25500

un blanc super brillant 100× plus brillant que tout ce qui existe.

Choisir l'alpha en fonction des couleurs

Si vous connaissez RVB3 (la couleur finale souhaitée), RVB2 (la couleur d'arrière-plan) et RVB1 (la couleur dont vous disposez et dont vous voulez faire varier l'opacité), et que vous cherchez uniquement A1, nous pouvons réorganiser les équations de la manière suivante :

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

Si ces valeurs sont différentes, vous ne pouvez pas les faire correspondre exactement, mais vous pouvez faire la moyenne des alphas pour vous en rapprocher le plus possible. Par exemple, il n'existe aucune opacité au monde qui vous permette de mettre du vert sur du rouge pour obtenir du bleu.

12voto

ephemer Points 83

J'ai créé un mixin LESS en utilisant la réponse de Phrogz. Vous avez votre mot à dire :

  1. l'aspect de la couleur
  2. avec un certain alpha
  3. sur un fond donné (par défaut le blanc)

Voici le code :

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

}

Utilisation comme suit :

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

Il est évident que cela ne fonctionne pas pour les combinaisons impossibles (comme mentionné par Phrogz), ce qui signifie que seuls des niveaux de transparence légers sont supportés. Voyez comment vous allez avec ça.

9voto

Tobia Points 2978

Gracias a Phrogz et éphémère Grâce aux excellentes réponses de l'auteur, voici une fonction SASS qui automatiquement calcule la meilleure couleur RGBA équivalente.

Vous l'appelez avec la couleur souhaitée et le fond existant, et il calculera la meilleure (c'est-à-dire la plus transparente) couleur RGBA équivalente qui donne le résultat souhaité à ±1/256 de chaque composante RVB (en raison des erreurs d'arrondi) :

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

Je viens de le tester avec un certain nombre de combinaisons (tous les thèmes de Bootswatch) et il fonctionne à merveille, tant pour les résultats d'obscurité sur lumière que pour ceux de lumière sur obscurité.

PS : Si vous avez besoin d'une précision supérieure à ±1/256 dans la couleur résultante, vous devrez savoir quel type d'algorithme d'arrondi les navigateurs appliquent lorsqu'ils mélangent des couleurs rgba (je ne sais pas si c'est standardisé ou non) et ajouter une condition appropriée à la fonction existante @while de sorte qu'il continue à augmenter $alpha jusqu'à ce qu'il atteigne la précision souhaitée.

6voto

Eric Points 36290

De la réponse de @Phrogz :

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

Donc :

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

Donc :

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

Notez que vous pouvez choisir n'importe quelle valeur de a1 et cela permettra de trouver les valeurs correspondantes de r1 , g1 y b1 nécessaire. Par exemple, un alpha de 1 vous indique que vous avez besoin de RGB1 = RGB3, mais un alpha de 0 ne donne aucune solution (évidemment).

1voto

La solution la plus pratique que j'ai trouvée jusqu'à présent : il suffit de mesurer la couleur obtenue à l'aide d'un outil de sélection de couleur, puis d'utiliser la couleur mesurée pour la superposition. Cette méthode permet d'obtenir une correspondance parfaite des couleurs.

J'ai essayé d'utiliser différents mixins mais à cause de l'erreur d'arrondi, j'ai quand même pu voir la différence à l'œil nu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X