¿Cómo invierto un color?

Sé que esto no invertirá directamente un color, simplemente lo “opondrá”. Me preguntaba si alguien sabía de una manera simple (unas líneas de código) para invertir un color de cualquier color dado?

En este momento tengo esto (que no es exactamente la definición de invertido, porque si lo paso a un color gris / gris devolverá algo extremadamente similar, por ejemplo, 127, 127, 127):

const int RGBMAX = 255; Color InvertMeAColour(Color ColourToInvert) { return Color.FromArgb(RGBMAX - ColourToInvert.R, RGBMAX - ColourToInvert.G, RGBMAX - ColourToInvert.B); } 

Depende de a qué te refieres con “invertir” un color

Su código proporciona un color “negativo”.

¿Está buscando transformar rojo en cian, verde en morado, azul en amarillo (y así sucesivamente)? Si es así, debe convertir su color RGB en modo HSV (lo encontrará aquí para realizar la transformación).

Luego solo necesita invertir el valor de Hue (cambie Hue por 360-Hue ) y vuelva a convertir al modo RGB.

EDITAR: como ha mencionado Alex Semeniuk, cambiar el Hue por (Hue + 180) % 360 es una mejor solución (no invierte el tono, pero encuentra el color opuesto en el círculo de color)

Puedes usar :

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

Invertirá MyColor.

Prueba esto:

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

Invierta los bits de cada componente por separado:

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

EDITAR: El operador ~ no trabaja con bytes automáticamente, se necesita conversión.

Lo que ya tienes es un RGB-Invertido. Hay otras formas de clasificar los colores y, por lo tanto, otras definiciones para el inverso de un color.

Pero parece que quieres un Color que contraste, y no hay una Inversión simple que funcione para todos los colores, incluido RGB (127, 127, 127).

Lo que necesita es 1) una conversión a HSV (consulte la respuesta de ThibThibs) e invierta el tono, pero también 2) compruebe si el tono no está cerca del centro y, en caso afirmativo, vaya a totalmente shiny o completamente oscuro.

Si desea cambiar todos los colores, intente con una función de rotación (desplazamiento o adición) en lugar de una función de volteo (inversión). En otras palabras, considere que el rango de 0 a 255 para cada color (rojo, verde y azul) debe envolverse, conectado en las puntas como un círculo de valores. Luego cambie cada color alrededor del círculo agregando algún valor y haciendo el mod 256. Por ejemplo, si su valor inicial para rojo es 255 y agrega 1, obtiene 0. Si cambia los tres colores por 128, se vuelve dramáticamente diferente valores para cada color original en la imagen, incluso los grises. Gris 127, 127, 127 se vuelve blanco 255, 255, 255. Gris 128, 128, 128 se vuelve negro 0, 0, 0. Hay un efecto fotográfico como el llamado Solarización, descubierto por casualidad por Man Ray en la década de 1930.

También puede hacer operaciones de rotación en cada color (rojo, verde, azul) en una cantidad diferente para realmente estropear una imagen.

También puede realizar operaciones de rotación en tono, cambiando el tono de cada color original en cierta cantidad en el círculo de tono, que altera todos los colores sin alterar el brillo, por lo que las sombras aún se ven como sombras, haciendo que las personas parezcan Simpsons o Smurphs para ejemplo.

El código para un cambio por 128 podría verse así:

 public static Color Invert(this Color c) => Color.FromArgb(cRInvert(), cGInvert(), cBInvert()); public static byte Invert(this byte b) { unchecked { return (byte)(b + 128); } } 

La manera más simple y perezosa en que lo hice funcionar con tener no solo triple 12x, sino valores mixtos, es esto:

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

Ahora, invertedColor tiene un color diferente que el original, incluso si tenemos 128, 128, 128 o cerca de ese valor de color.