What is a good way to store color? - c++

I started to make "game of life" and I thought, what if I could have more states than 1 or 0.
But then I need different colors. I want the colors to be linked to a grid/object (the grid is a class).
What is a good/decent way to store color pallets for fast/easy access?
My current less than ideal solution was to have 4 pointers to memory for each red, green, blue and alpha value.
In my class I had a function to set the color of value v to rgba:
SetColor(v, r, g, b, a) //Set v to the appropriate color values
I would like to keep this function to easily modify a color.

What I use is something really simple: 4 floats
struct Color {
float r, g, b, a;
};
Then, you can have something like a color pallete:
// a Palette of 8 colors:
using palette_t = std::array<Color, 8>
palette_t myPalette { /* ... */ };
Then, in your grid or object class, you can reference the color with an index:
struct Grid {
// lot's of code
private:
std::size_t colorIndex = 0;
};
But then you asked how to have easy access to the color (I guess the easy access is from within the Grid class)
There is a lot of solution that can exists, and most will depend of your project structure. This is one idea many others. I hope it will inspire you.
You can store a function that return the right color:
struct Grid {
// lot's of code
private:
std::size_t colorIndex = 0;
std::function<Color(std::size_t)> color;
};
And then, have something that create your grid correctly:
struct GridCreator {
GridCreator(const palette_t& aPalette) : palette{aPalette} {}
Grid create(std::size_t color) const {
Grid grid;
// create the grid
grid.color = [this](std::size_t index) {
return palette[index];
};
return grid;
}
private:
const palette_t& palette;
};
Then you got free access to your color palette without directly knowing that the palette exists from the Grid class.

Have an array of colors:
std::vector<std::array<unsigned char, 4>> palette {
{255, 0, 0, 255}, // red
{0, 255, 0, 255}, // green
{0, 0, 255, 255}, // blue
};
Then for each field store the index in the array (of type size_t). Example:
auto id = field[5][2];
auto color = palette[id];
auto r = color[0], alpha = color[3];
Changing a color is as simple as:
palette[id] = {255, 0, 0, 127};
For adding new colors, use:
palette.push_back({255, 0, 0, 127}).
Alternatively, you can define a simple struct so that you can use color.r, color.alpha etc. and write a constructor for easy color creation.
Mind this example is C++11 code.

Enums are perfect for Colors kind of structure.
More code readability.
Better compiler-time optimizations.
enum Color { red, green, blue };
Color r = red;
switch(r)
{
case red : std::cout << "red\n"; break;
case green: std::cout << "green\n"; break;
case blue : std::cout << "blue\n"; break;
}
For your special case.
You can store color for each point as a single integer.
uint32_t point_color = field[5][2].color;
unsigned char* color = (unsigned char*)point_color[id];
auto r = color[0], alpha = color[3];
/////
void SetColor(uint32_t& point_color,unsigned char r,
unsigned char g,unsigned char b,unsigned char a){
point_color=r | (b*(1<<8)) | (g*(1<<16)) | (a*(1<<24));
}
Pros of this structure
lesser messy.
faster bit operations only.
lesser memory.

Your question is dualistic:
What is a good way to store color?
what is a good/decent way to store color pallets?
If you really only want to store a colour, my advise would be not to store the colours as references, but to store the RGB values in one INT32 inside a class where you can get and set the Reg / Green / Blue values. Compare this with how .NET does this.
The advantage of this method is that it does no more space than using pointers and it is fast in get / set / comparisons.
A color pallette is a collection of colours. This is quite often used if you want to switch all used colours into a different colour. For instance if you want all light-blue colours in to misty-blue colours, and all fire-red colours into brick-red.
This is used by defining a palette as a pre-defined sized array or RGB values. Historically a palette contains 16, 64, or 256 values, or sometimes 2 if you only want black/white pictures.
If you use a palette, every dot in your grid has an index in your palette array and your grid has a current pallette. The RGB value of point X of grid G is then G.CurrentPallette[X.PaletIndex]. Changing all colours of your grid at once means switching to a different palette: G.CurrentPalette = otherPalette. This is a really fast and efficient way of changing the colours in your grid
Whether to use the RGB method or the Palette method depends on what you want:
Do you only want to use a subset of all possible colours, and do you want to change the complete subset into a different subset: use the Palette method
Do you want to change the colour of dots with a certain state, for instance change all yellow dots to green, use the palette method: change the color yellow in your palette to green
However, if you only want to change individual dots on your grid it is probably more efficient to use the RGB method.

any color value has an interval from 0 through 255 so you need 3 unsigned char variables and another one for alph. we make a whole thing, mapping them an a struct:
typedef struct Color
{
unsigned char _ucRed;
unsigned char _ucGreen;
unsigned char _ucBlue;
unsigned char _ucAlpha;
}COLOR;

Related

What index order does Opencv's cv::Mat::forEach<> function's position argument correspond to?

I've been trying to use opencv::forEach, but the position argument seems to correspond to the z,y,x, position, instead of x,y,z position. I can't find this stated anywhere though, and OpenCV appears to imply the opposite in their documentation.
// Creating 3D matrix (255 x 255 x 255) typed uint8_t
// and initialize all elements by the value which equals elements position.
// i.e. pixels (x,y,z) = (1,2,3) is (b,g,r) = (1,2,3).
int sizes[] = { 255, 255, 255 };
typedef cv::Point3_<uint8_t> Pixel;
Mat_<Pixel> image = Mat::zeros(3, sizes, CV_8UC3);
image.forEach<Pixel>([&](Pixel& pixel, const int position[]) -> void {
pixel.x = position[0];
pixel.y = position[1];
pixel.z = position[2];
});
I've looked this up outside of OpenCV's documenation, but apparently 99% of people don't use this for more than 1D matrices. I've seen no documentation state explicitly what order the position elements are in. And OpenCV is not shy about using either natural, or C order indexing, the at<T> function for example supports both.
Each pixel is stored in BGR format

How to remove small shapes from an image?

I have this image:
I have the following functions:
void DrawPixel(int x, int y, unsigned char r, unsigned char g, unsigned char b);
void ReadPixel(GLint x, GLint y, unsigned char &r, unsigned char &g, unsigned char &b);
Objective
Remove the small shapes of the image, there are 4 small shapes in the image, I want to remove them. One way to do this would be by how many red pixels each shape has, if one shape has less than 200 red pixels for example, I'll remove it from the image by painting it in black. This is just a form of solution that I imagined, if anyone has any other alternative it will be welcome.
What I've tried
void RemoveLastNoises(){
int x,y;
int cont = 0;
unsigned char r,g,b;
int xAux;
for(y=0;y<NewImage.SizeY()-0;y++){
for(x=0;x<NewImage.SizeX()-0;x++){
NewImage.ReadPixel(x,y,r,g,b);
if(r == 255){
cont = 0;
while(r == 255){
NewImage.ReadPixel(x+cont,y,r,g,b);
cont = cont + 1;
}
if(cont < 300){
NewImage.DrawPixel(x,y,255,255,255);
}
}
xAux = x;
x = x+cont;
}
x = xAux;
}
}
This works, but only counts how many red pixels it has in a row (x), I found it interesting to put it here as a reference. Anyway, any idea to remove the small shapes will be welcome.
Note:The larger shapes are not to be modified, the height and width of the image is larger, I decrease the dimensions for the question to be readable.
There is a set of nonlinear filters that are called morophological filters.
They use "and" and "or" combination to create filter masks.
What you need to do is implement a closing. OpenGL does not privde such functions thus, you have to write the code on your own. To do so you
If they are always red just use the red channel as grey-scale image
Create a binary image from the created image
Inverse the image from 2
Create a filter mask with '1's that is large enough to cover the small parts you want to rease
Do A Dilation (https://en.wikipedia.org/wiki/Dilation_(morphology)) on the image with the filter mask
Do an Erosion (https://en.wikipedia.org/wiki/Erosion_(morphology)) on the image with the same filter mask or a slightly smaller one
Invert the image again
5 and 6 are describing a "Closing" https://en.wikipedia.org/wiki/Closing_(morphology)

C++ DirectX DrawText in multiple colors

I use ID3DXFont interface to draw text and that perfectly suits my needs as long as complete string is in single color. Now I'd wish to draw a string but in multiple colors. For instance "abc", with a in red, b in yellow, etc.
I know that I could draw each letter on its own, giving a different Color parameter to DrawText each time. The only issue with this is that I do not know how many pixels should I offset after each letter because every letter has a different width. Hardcoding widths is not really a good solution.
The ID3DXFont interface doesn't allow you to draw multiple colors within a single invocation of DrawText. However, it can give you the bounding rectangles of any text that you wish to draw using the DT_CALCRECT flag, so you do not need to hardcode widths of particular glyphs within your font. This also means you can switch the font and/or size of the font without needing to modify your drawing code, or hardcoding new width. For example:
ID3DXFont* font = ...;
const char* strings[] = { "A", "i", "C" };
D3DCOLOR colors[] = { D3DCOLOR_ARGB(255, 255, 0, 0), D3DCOLOR_ARGB(255, 0, 255, 0), D3DCOLOR_ARGB(255, 0, 0, 255) };
RECT r = { 10,10,0,0}; // starting point
for (int i = 0; i < _countof(strings); ++i)
{
font->DrawText(NULL, strings[i], -1, &r, DT_CALCRECT, 0);
font->DrawText(NULL, strings[i], -1, &r, DT_NOCLIP, colors[i]);
r.left = r.right; // offset for next character.
}
Note: I have used 'i' instead of 'b' from your example, because it makes it apparent that the rectangles are correct, as 'i' is (generally) a very thin glyph. Also note that this assumes a single line of text. The calculated rectangle also includes height, so if you are doing multiple lines, you could also use the height of the calculated rectangle to offset the position.

passing properties of an object as a string

I have an unordered map that is supposed to check if a pen exists given the color, and the width of the pen. I'm currently trying to do a lookup by string. If it’s already in the map, that means I already created a Pen of that type. If it isn’t already in the map, I want to create a new Pen and set the color and weight, and add that to the unordered_map.
std::unordered_map<std::string, std::shared_ptr<Gdiplus::Pen>> mymap;
The properties of the pen that i want are the color and the width... as you can see the color comes in the format(0,0,0) and the width is just a float number. I was thinking about doing a string as such: "(R,G,B);W" where R, G, B correspond to the colors and W corresponds to the width of the Pen, but that seems too complex.
Gdiplus::Pen pen(Color(0, 0, 0));
pen.getWidth();
I was wondering if there is a simple way to pass those properties as a single string or if there is a better way to go around my problem.
My string is supposed to see if the pen exists. it checks the pen color and the width.
My assumption is that you are checking to see if a pen exists or not.
Instead of putting things into a string, put them into a structure and use the structure in a container.
struct Pen_Properties
{
unsigned int r,g, b;
unsigned int width;
bool operator<(const Pen_Properties& p)
{
bool result = true;
if (r != p.r)
{
result = r < p.r;
}
else
{
if (g != p.g)
{
result = g < p.g;
}
else
{
// And so on.
}
}
};

How do I create a color bar (TV test pattern)

I need to create a colorbar like THIS
I use a scaled array of floats between 0 and 1.
Now I want to compute the RGB color from this float. How to do it? Want to write it in C/c++ so I think I need 2 functions.
The first function to build the colorbar with one parameter like STEPSIZE and the second function need the value and must just return the array index of the colorbar.
I couldn't find it on google, so please help me.
What you are referring to here is the 100% EBU Color Bars (named after the standards body, the European Broadcasting Union). This is not the same as the full SMPTE RP 219-2002 color bars, which have other features including gradients and the PLUGE (Picture Line-Up Generation Equipment), described in the Wikipedia article on Color Bars.
The EBU Color Bars consist of 8 vertical bars of equal width. They are defined in the same way for both SD and HD formats. In the RGB color space, they alternate each of the red, green and blue channels at different rates (much like counting in binary) from 0 to 100% intensity. Counting down from white, in normalised RGB form (appearing left to right):
1, 1, 1: White
1, 1, 0: Yellow
0, 1, 1: Cyan
0, 1, 0: Green
1, 0, 1: Magenta
1, 0, 0: Red
0, 0, 1: Blue
0, 0, 0: Black
So the blue channel alternates every column, the red channel after two columns, and the green after four columns. This arrangement has the useful property that the luminance (Y in YCb'Cr' colour space) results in a downward stepping plot.
To render using 8-bit RGB (most commonly found in desktop systems), simply multiply the above values by 255. The EBU bars come in 75% and 100% variants, based on the intensity of the white column. The SMPTE color bars typically use 75% levels as a reference.
Here is some simple C code to generate 100% EBU color bars and save the result as a PGM file:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
// PAL dimensions
static const unsigned kWidth = 720;
static const unsigned kHeight = 576;
typedef struct
{
uint8_t r;
uint8_t g;
uint8_t b;
} RGB;
int main(int argc, char* argv[])
{
const RGB BAR_COLOUR[8] =
{
{ 255, 255, 255 }, // 100% White
{ 255, 255, 0 }, // Yellow
{ 0, 255, 255 }, // Cyan
{ 0, 255, 0 }, // Green
{ 255, 0, 255 }, // Magenta
{ 255, 0, 0 }, // Red
{ 0, 0, 255 }, // Blue
{ 0, 0, 0 }, // Black
};
// Allocate frame buffer
size_t frameBytes = kWidth*kHeight*sizeof(RGB);
RGB* frame = malloc(frameBytes);
unsigned columnWidth = kWidth / 8;
// Generate complete frame
for (unsigned y = 0; y < kHeight; y++)
{
for (unsigned x = 0; x < kWidth; x++)
{
unsigned col_idx = x / columnWidth;
frame[y*kWidth+x] = BAR_COLOUR[col_idx];
}
}
// Save as PPM
FILE* fout = fopen("ebu_bars.ppm", "wb");
fprintf(fout, "P6\n%u %u\n255\n", kWidth, kHeight);
fwrite(frame, frameBytes, 1, fout);
fclose(fout);
free(frame);
return 0;
}
This should be readily adaptable to any other language. There's probably no need for using float unless you're implementing this on a GPU (in which case the algorithm would be quite different). There is much scope for optimization here; the code is written for clarity, not speed.
Note that while it is possible to generate a perfect digital representation of the color bars in a computer, this will not be safe for broadcast. The transitions between "perfect" color bars would require infinitely high bandwidth to accurately represent. So if the test image is to be transmitted via analog broadcast equipment, it must be bandwidth-limited by a low-pass filter (eg. ~4.3MHz for PAL). This is why you notice the "fuzzy" boundaries in between each column; these contain intermediate values between the pure colors.
Also note that it is not possible to accurately represent the SMPTE color bars in the RGB color space. This is because certain critical values are specified in the YCb'Cr' color space (notably in the PLUGE region) which are outside the gamut of RGB (either SD or HD). You can create something that approximates the values (eg. a very dark blue) but they are not correct. So unless you are representing the test frame in YCb'Cr', stick to EBU bars only (the upper 2/3).
RGB uses bytes, so assuming your array of floats is something like
float scaledColor[3]; // 0 = R, etc., all 0.0 < scaledColor[x] < 1.0
then you can do:
unsigned char r = (unsigned char)(255 * scaledColor[0]);
unsigned char g = (unsigned char)(255 * scaledColor[1]);
unsigned char b = (unsigned char)(255 * scaledColor[2]);
This will of course only work if the values in the floats are really in the range from 0.0 to 1.0.
The simplest solution:
const unsigned char* getColour(float x) /* 0 <= x < 1 */
{
static const unsigned char bar[][3] = {
{255,255,255},
{255,255,0},
// ... fill in all the colours ...
{0,0,0}
};
return bar[(int)(x*sizeof(bar))];
}
Then you can use it to generate bars of any width.
My google-fu turned up that you want the upper third of a SMPTE color bar pattern.
Wikipedia says:
In order from left to right, the colors are gray, yellow, cyan, green,
magenta, red, and blue.
So the easiest way is to simply hard code the respective RGB color codes if you only need those. The article also mentions how those colors can be generated but this seems a lot more difficult and isn't really worth the effort for seven colors.