How do I invert a colour?

こ雲淡風輕ζ 提交于 2019-11-26 05:29:26

问题


I know that this won\'t directly invert a colour, it will just \'oppose\' it. I was wondering if anyone knew a simple way (a few lines of code) to invert a colour from any given colour?

At the moment I have this (which isn\'t exactly the definition of an invert, because if I pass it a grey / gray colour it will return something extremely similar e.g. 127, 127, 127):

const int RGBMAX = 255;

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

回答1:


It depends on what do you mean by "inverting" a color

Your code provides a "negative" color.

Are you looking for transform red in cyan, green in purple, blue in yellow (and so on) ? If so, you need to convert your RGB color in HSV mode (you will find here to make the transformation).

Then you just need to invert the Hue value (change Hue by 360-Hue) and convert back to RGB mode.

EDIT: as Alex Semeniuk has mentioned, changing Hue by (Hue + 180) % 360 is a better solution (it does not invert the Hue, but find the opposite color on the color circle)




回答2:


You can use :

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

It will invert MyColor.




回答3:


Try this:

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



回答4:


Invert the bits of each component separately:

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

EDIT: The ~ operator does not work with bytes automatically, cast is needed.




回答5:


What you already have is an RGB-Invert. There are other ways to classify colors and hence other definitions for the Inverse of a Color.

But it sounds like maybe you want a contrasting Color, and there isn't a simple Inversion that is going to work for all colors including RGB(127, 127, 127).

What you need is 1) a conversion to HSV (see ThibThibs answer) and invert the Hue, but also 2) check if the Hue isn't to close to the middle and if so go to either fully bright or fully dark.




回答6:


If you want to change every color, try a rotational function (shifting or adding) rather than a flipping function (inverting). In other words, consider the range of 0 to 255 for each single color (red, green, and blue) to be wrapped, connected at the tips like a circle of values. Then shift each color around the cirle by adding some value and doing mod 256. For example, if your starting value for red is 255, and you add 1, you get 0. If you shift all three colors by 128, you get dramatically different values for every original color in the picture, even the grays. Gray 127, 127, 127 becomes white 255, 255, 255. Gray 128, 128, 128 becomes black 0, 0, 0. There's a photographic effect like that called Solarization, discovered by accident by Man Ray in the 1930's.

You can also do rotational operations on each color (red, green, blue) by a different amount to really mess up a picture.

You can also do rotational operations on hue, shifting the hue of every original color by some amount on the hue circle, which alters all the colors without altering the brightness, so the shadows still look like shadows, making people look like Simpsons or Smurphs for example.

The code for a shift by 128 could look like:

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



回答7:


The most simple and lazy way I made it to work with having not only triple 12x, but mixed values, is this:

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

Now, invertedColor has a different color that the original, even if we have a 128, 128, 128 or close to it color value.




回答8:


I've created this simple function for VB.NET:

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

And this one for C#:

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


来源:https://stackoverflow.com/questions/1165107/how-do-i-invert-a-colour

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!