I'm trying to paint a full RGB color map that eventually will allow a user to select a color by tapping that visual map at any point. My current code is the following:
- (void)drawRect:(CGRect)rect
{
CGContextRef c = UIGraphicsGetCurrentContext();
for (float x=0; x<320; x++) {
for (float y=0; y<416; y++) {
float r = x / 320;
float g = y / 416;
float b = (y < 208) ? y / 208 : (416 - y) / 208;
CGContextSetRGBFillColor(c, r, g, b, 1.0);
CGContextFillRect(c, CGRectMake(x, y, 1, 1));
}
}
}
The result is not too bad but I'm not satisfied yet. The spectrum misses bright colors including white. The reason is clear: red, green and blue will never reach 1.0 at the same time.
Do you have any advise how to improve that map so it represents the full spectrum of the RGB color space?
Thanks for all your input!
UPDATE:
As suggested by Josh Caswell I've used the HSB color space and the following code:
- (void)drawRect:(CGRect)rect
{
CGContextRef c = UIGraphicsGetCurrentContext();
int size = 20;
for (float x=0; x<320; x+=size) {
float s = x < 160 ? 1 : (320 - x) / 160;
float b = x < 160 ? x / 160 : 1;
for (float y=0; y<416; y+=size) {
float h = y / 416;
[[UIColor colorWithHue:h saturation:s brightness:b alpha:1.0] setFill];
CGContextFillRect(c, CGRectMake(x, y, size, size));
}
}
}
This results in the following output which is perfect for my needs.
Thanks for all input!
RGB colorsWhite: RGB(255,255,255) Red: RGB(255,0,0)
For example, rgb(255, 0, 0) is displayed as red, because red is set to its highest value (255) and the others are set to 0. To display black, set all color parameters to 0, like this: rgb(0, 0, 0). To display white, set all color parameters to 255, like this: rgb(255, 255, 255).
The second reason we don't use RYB is because the human eye is more sensitive to green. You are most sensitive to green, then to red, and a tiny bit to blue. Because these are the colors the human eye notices most, the RGB color model is used most often to create different color spaces.
To start mixing in RGB, think of each channel as a bucket of red, green, or blue paint. With 8 bits per channel, you have 256 levels of granularity for how much of that color you want to mix in; 255 is the whole bucket, 192 = three quarters, 128 = half bucket, 64 = quarter bucket, and so on.
Well, you're trying to flatten a three-dimensional object onto a plane. An RGB color basically represents a point inside of a cube. Mapping the RGB solid onto a surface may be mathematically possible, but probably won't be particularly intuitive for this color-selection purpose.
You might have better luck using HSB, which is more like a cylinder with hue as angle around the circumference. You could "unroll" the cylinder, mapping hue to the y coordinate, then vary either brightness or saturation along the x axis -- you can do some simple testing to decide which component is more important for your application. A two-finger-swipe could be used for the third component if you felt it was necessary to include it.
HSB with saturation on X-axis:
With brightness on X-axis:
With saturation and brightness equal and both on X-axis:
If you need white, which occurs when S = 0%, B = 100%, you could either stick a strip along one side, or try S = 1/B.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With