What I have: A class that recieves a BitmapImage and creates matrices for ARGB values.
What I want: To identify a specific type of picture. This picture always has a green oval in its center. But sometimes, it is a light green, sometimes a darker green, sometimes a mixture of several types of green, sometimes with shadows.
The question: What exactly can be counted as "green", regarding the ARGB-values?
Update:
Calculating the distance to pure green (0,255,0) seems like a good approach. But how to do this in a good manner?
"Calculating the distance to pure green (0,255,0) seems like a good approach."
Don't go down this rabbit hole. You can't (or shouldn't at least) apply Pythagoras to the RGB colour space to get a "distance".
What you should look at is converting to a different colour space. HSL is good because it gives a single value for colour which is Hue. You can then define an acceptable range of "green" and ignore saturation.
Related
I'm using the ImageSharp library (available on NuGet as 1.0.0-beta0001) for image generation and manipulation in .NET Core 2.0, and have encountered something that I can't seem to find a way around.
Using this example as a basis, I'm trying to round the corners of a white image. What I'm finding is that the transparent IPath corners being punched out end up antialiasing dark, as if the transparent "color" were black or gray (whereas it really shouldn't be considered any color at all).
Here's the upper-right quadrant of the image to demonstrate what I mean:
I tried all the options for PixelBlenderMode at this part of the code and none have produced what I'm after:
img.Mutate(x => x.Fill(Rgba32.Transparent, corners, new GraphicsOptions(true)
{
BlenderMode = PixelBlenderMode.Src // enforces that any part of this shape that has color is punched out of the background
}));
The problem you are seeing is the consequence of incorrect pixel sampling. Pixels with low transparency were affecting the average value of the individual components too much.
Quoting some of the text from below link as an example as it explains the issues well.
A pixel in the white area has a color of RGBA(1.00, 1.00, 1.00, 1.00). A pixel in the red area has color RGBA(1.00, 0.00, 0.00, 0.10). If you average those numbers together, you get (1.00, 0.50, 0.50, 0.55). That’s the color a typical pixel on the boundary would have if you resize the image in the straightforward way.
But that color – a half-opaque light red – is the wrong color! You can see a faint red halo around the border, which shouldn’t be there:
http://entropymine.com/imageworsener/resizealpha/
The fix is simple, values must be premultiplied by their alpha component first before sampling.
However, I don't know whether this issue is happening due to resizing the generated image (fixed in the latest nightlies), or during the fill process. I would need to see sample code first to be sure as I do not know how you are providing the source image.
I need to generate a random background color that's visually pleasing for three types of text color: ARGB(255,255,255,255), ARGB(63,255,255,255), and ARGB(255,0,0,0). The colors are white, white at 0.25 opacity, and black. I have yet to see an example on SO or somewhere else that compares a color against multiple colors to decide if there is good contrast between them (The comparison is done between two colors only). I don't fully understand color theory, so I'm looking for help.
Contrasting colors to white are any dark. On other hand, contrasting colors to black are any light. So it's difficult to choose a contrasting color to both white and black.
It may be some average gray color or any other color with the same brightness.
The brightness may be calculated with this formula:
int brightness = (int)(0.30 * red + 0.59 * green + 0.11 * blue);
Let's fix the brightness value to average (i.e. 128), and randomly select red and green values. Then we can calculate blue:
var random = new Random();
var red = random.Next(128);
var green = random.Next(128);
var blue = (int)(128 - 0.30 * red - 0.59 * green);
The resulting color is quite contrasting to both black and white.
Firstly you need to get yourself familiar with color spaces and decide what will make a random color visually appealing. A color basically can be represented as three components in many different spaces. The preferred representation for computers is RGB with is the amount of red, green and blue that conforms the color. However, for the human eye the HSV (hue, saturation, value) is probably easier to understand. In this color space the saturation represents how 'saturated' is the color, i.e. the gray scale range has a saturation of zero since it really doesn't represent a color. The value (or intensity) think of it as the brightness and the hue sort of gives you the in what direction of the spectrum (think on a rainbow) the color belong.
The alpha value is not part of the color itself, it rather specify how a particular color mixes with the background (i.e. the resulting color is calculated as the weighted sum of the front color by its alpha component and the background color)
Now in terms of selecting a visually appealing color that is more complicated and depends more on each individual taste. You normally achieve a high contrast color by selecting another color whose distance in HSV color space is big enough. In fact, selecting a color with one of the two components the same (e.g. same saturation and intensity) but very different hue will give you a color that will make high contrast with the original one. The conversion formulas from RGB to HSV and viceversa can be found here. Hope this helps.
Say I have two colors, red and pink. How would I define a relationship between them such that I would be able to use it to get say, light blue from blue? The 'pink' isn't just light red, so I don't want to use ControlPaint.Light. The easiest way I can think of is to get the HSB difference between red and pink and just add that to the base blue color, but c# lacks methods to convert those HSB values back to RGB and I would rather not write my own if I can help it. Is there another way?
If you want to adjust the lightness of a color without changing the hue, your best option is to convert the RGB color to HSL. Then adjust the lightness by a certain amount. Then convert it back to RGB if needed.
You can find a lot of examples of code to use to do the conversion such as the following:
Convert RGB bytes to HSL and back?
How can I create a grid of all possible RGB color combinations in a logical sequence?
Something like this:
Using 256 values per color would yield (256^3=) 16,777,216 possible colors that could be arranged into a (sqrt of 16,777,216=) 4,096 x 4,096 square.
I know how to make an array of colors and then display them, but what I'm asking for is the logic behind making smooth transitions between the colors.
Don't think in RGB, think in the HSL (Hue, Saturation, lightness) or HSV color space. They are much closer to what humans perceive as 'close' to each other.
To get the colors like the ones in your example:
Leave Saturation at '1'.
To go across (different colors, RED->YELLOW->GREEN->ETC), increase the 'Hue'.
To go down (where the color gets darker) decrease the lightness.
Here is an article on HSL and HSV color space. In that article they have some conversion algorithms back to RGB, but here is a nice easy article for the conversion in C.
EDIT: And one in c#
You can't reach all possible colors with an arrangement like in the linked image on a 4kX4k square because the RGB colors displayed by computers are in a three-dimensional space. That's why there are different color models in graphics programs which usually display three value selectors or at least pull out one dimension to a linear selector control and leave the other two dimensions in a squared control.
Sometimes you also see an arrangement in a hexagonal control or a triangular color and a separate brightness selector.
The linked image misses the grey colors completely. It is actually a combined selector for Hue and Lightness in HSL color space. The middle line with the intense colors can be easily determined with starting one base color, step by step adding the next base color, when reaching the max value reducing the first color, then transition with the same schema to the third and finally back to the first color. On the way to the top, there's a linear transition to white, on the way down to black.
In the end you have all colors on the six bounding planes in the color space but the whole space between the planes is not yet covered. For that, you need a separate selector for the saturation of the color. Reducing the saturation from the maximum level covers the grey colors.
If you really want all colors on a squared space, you can create blocks of 256x256 in size that repeat again and again with slight addition of the third color.
In general representing 3d space on a plane is hard especially if you want to see something inisde non-transparent cloud... So dropping intensity maybe one approach.
Look into HSI/HSL/HSV - http://en.wikipedia.org/wiki/HSI_color_space.
I am developing an application where I have to play around with some RGB colors. Actually, I have RGB and its HEX/HSV equivalent.
Now, I am trying to dynamically generate matching colors for a selected color, lets say 'Red', then I would like to generates 5 matching colors for red, ex: black, orange, other teint of red, some blue, etc...
I don't have knowledge about how colors and their calculation work, so any help, hints, code snippets would be greatly appreciated.
HSV is a much better colorspace to manipulate colors in than RGB, because HSV's axes correspond directly to useful transformations of a color.
To make a color brighter or more saturated, increase its saturation. To desaturate (make grayscale), decrease the saturation. Decreasing the V(alue) of a color makes it darker - all colors with V of 0 are black. Changing the hue alters the color itself, moving around a color wheel. See Wikipedia's article on HSV for more details.
What transformations you do depend on what sort of related colors you want to generate. If you want complementary colors, for instance, you probably want to take the color, leave the S and V unmodified, and generate colors 1/3rd and 2/3rds of the way around the color wheel from the current color. Brighter and darker versions can be made by varying the value, while more and less 'intense' colors can be made by varying the saturation.
RGB colors are just a space in memory where you have three values, each ranging from 0 to 255. Red, for example, is just 255, 0, 0... 255 (maximum) in the "Red" field of the memory location, and zero in the "Blue" and "Green". It's when you mix these different values around that you start to get the almost infinite array of colors we see on our screens.
I can't quite tell you what to do with your code without seeing it, but I can tell you that if you have a control or object where you have a RGB property, you can modify the values in said property to make the color of the control or object any color you want. Experiment to see what values produce the colors you want, then enter these into the property fields in the dynamic manner that you seek.