web-dev-qa-db-fra.com

Comment inverser une couleur?

Je sais que cela n'inversera pas directement une couleur, il faudra simplement "s'y opposer". Je me demandais si quelqu'un connaissait un moyen simple (quelques lignes de code) d'inverser une couleur à partir d'une couleur donnée?

Pour le moment, j'ai ceci (qui ne correspond pas exactement à la définition d'un inverti, car si je lui passe une couleur gris/gris, il retourne quelque chose d'extrêmement similaire, par exemple 127, 127, 127):

const int RGBMAX = 255;

Color InvertMeAColour(Color ColourToInvert)
{
    return Color.FromArgb(RGBMAX - ColourToInvert.R, 
      RGBMAX - ColourToInvert.G, RGBMAX - ColourToInvert.B);
}
35
ThePower

Cela dépend de ce que vous entendez par "inverser" une couleur

Votre code fournit une couleur "négative".

Cherchez-vous le rouge transformable en cyan, vert en violet, bleu en jaune (et ainsi de suite)? Si tel est le cas, vous devez convertir votre couleur RVB en mode HSV (vous trouverez le mode ici pour effectuer la transformation).

Ensuite, il vous suffit d’inverser la valeur Teinte (changez Hue de 360-Hue) et de reconvertir en mode RVB.

EDIT: comme Alex Semeniuk l’a mentionné, changer Hue par (Hue + 180) % 360 est une meilleure solution (cela n’inverse pas la teinte, mais la couleur opposée est indiquée sur le cercle de couleur).

47
ThibThib

Vous pouvez utiliser :

MyColor=Color.FromArgb(MyColor.ToArgb()^0xffffff);

Cela inversera MyColor.

17
Remy

Essaye ça:

uint InvertColor(uint rgbaColor)
{
    return 0xFFFFFF00u ^ rgbaColor; // Assumes alpha is in the rightmost byte, change as needed
}
10
korona

Si vous souhaitez changer toutes les couleurs, essayez une fonction de rotation (décalage ou ajout) plutôt qu'une fonction de retournement (inversion). En d'autres termes, considérez la plage comprise entre 0 et 255 pour chaque couleur (rouge, vert et bleu) à encapsuler, connectée aux extrémités comme un cercle de valeurs. Puis déplacez chaque couleur autour du cercle en ajoutant une valeur et en faisant le mod 256. Par exemple, si votre valeur de départ pour le rouge est 255 et que vous ajoutez 1, vous obtenez 0. Si vous décalez les trois couleurs de 128, vous obtenez une différence considérable. valeurs pour chaque couleur d'origine dans l'image, même les gris. Les gris 127, 127, 127 deviennent blancs 255, 255, 255. Les gris 128, 128, 128 deviennent noirs, 0, 0, 0. Il existe un effet photographique comme celui appelé Solarization, découvert par hasard par Man Ray dans les années 1930.

Vous pouvez également effectuer des opérations de rotation sur chaque couleur (rouge, vert, bleu) d'une quantité différente pour vraiment gâcher une image.

Vous pouvez également effectuer des opérations de rotation sur la teinte, en décalant légèrement la teinte de chaque couleur d'origine sur le cercle de teinte, ce qui modifie toutes les couleurs sans altérer la luminosité. Exemple.

Le code pour un décalage de 128 pourrait ressembler à ceci:

public static Color Invert(this Color c) => Color.FromArgb(c.R.Invert(), c.G.Invert(), c.B.Invert());

public static byte Invert(this byte b) {
    unchecked {
        return (byte)(b + 128);
    }
}
5
Raxin

Inverser les bits de chaque composant séparément:

Color InvertMeAColour(Color ColourToInvert)
{
   return Color.FromArgb((byte)~ColourToInvert.R, (byte)~ColourToInvert.G, (byte)~ColourToInvert.B);
}

EDIT: L'opérateur ~ ne fonctionne pas automatiquement avec les octets, une conversion est nécessaire.

5
Kenan E. K.

Ce que vous avez déjà, c'est un inverser RVB. Il existe d'autres moyens de classer les couleurs et, par conséquent, d'autres définitions pour l'inverse d'une couleur. 

Mais il semble que vous souhaitiez peut-être une couleur contrastante, et il n’ya pas d’inversion simple qui fonctionne pour toutes les couleurs, y compris RVB (127, 127, 127). 

Ce qu'il vous faut, c'est 1) une conversion en HSV (voir la réponse de ThibThibs) et inverser la teinte, mais aussi 2) vérifier si la teinte n'est pas trop proche du milieu et si c'est le cas, optez pour une luminosité totale ou une obscurité totale. 

5
Henk Holterman

La manière la plus simple et la plus paresseuse que je me suis faite de fonctionner avec non seulement un triple 12x, mais des valeurs mixtes est la suivante:

Color invertedColor= Color.FromArgb(fromColor.ToArgb() ^ 0xffffff);

if (invertedColor.R > 110 && invertedColor.R < 150 &&
    invertedColor.G > 110 && invertedColor.G < 150 &&
    invertedColor.B > 110 && invertedColor.B < 150)
{
    int avg = (invertedColor.R + invertedColor.G + invertedColor.B) / 3;
    avg = avg > 128 ? 200 : 60;
    invertedColor= Color.FromArgb(avg, avg, avg);
}

Maintenant, invertedColor a une couleur différente de celle de l'original, même si nous avons une valeur de couleur de 128, 128, 128 ou proche de celle-ci.

1
Christos Lytras

J'ai créé cette fonction simple pour VB.NET:

Public Shared Function Invert(ByVal Culoare As Color) As Color
    Return Color.FromArgb(Culoare.ToArgb() Xor &HFFFFFF)
End Function

Et celui-ci pour C #:

public static Color Invert(Color Culoare)
{
    return Color.FromArgb(Culoare.ToArgb() ^ 0xFFFFFF);
}