Hey

I'm writing a color class, and I want to have a constructor that can take in an unsigned int like 0x00FF00FF and interpret it as fully opaque green. I have code for that (I think it should work, could someone check it?):

rzb::color::color(unsigned int hex)
{
	m_red = (hex & 0xff000000)/(0x00ffffff);
	m_green = (hex & 0x00ff0000)/(0x0000ffff);
	m_blue = (hex & 0x0000ff00)/(0x000000ff);
	m_alpha = (hex & 0x000000ff);
}

The thing is, I'd like the user to also be able to give this input: 0x00FF00, and have that also be interpreted as opaque green (alpha value would be FF by default), but I can't figure out how to do that. Is there a way to check the length of a number passed as input (or some other algorithm to do what I want). I can't just compare the values, because 0xffffff (opaque white) comes out to 16,777,215, but 0x0000ffee (slightly transparent green) comes out to 65,518, a smaller value, even though it's the the larger form.

Recommended Answers

All 6 Replies

Wow, nvm - just figured it out.

Have alpha be first, not last.

But if someone could confirm that and/or check the above code I'd appreciate it.

Wow, nvm - just figured it out.

Have alpha be first, not last.

But if someone could confirm that and/or check the above code I'd appreciate it.

I don't think you want to be dividing by 0xff, 0xffff, and 0xffffff, but rather by 0x100, 0x10000, and 0x1000000. In particular, 0xff00 / 0xff = 0x100 = 256, which is not in the range of 0 to 255. You can also speed things and use the shift right (>>) operator rather than divide:

unsigned int red = (hex & 0x00ff0000) >> 16;

Oh, you're right.

But actually, I dropped the system of using different members for red, green, blue, and alpha. I'm just using a single hex value as a member to save space.

Edit:
Just wondering, would this be any faster:

unsigned int red = (hex << 8) >> 16;
//or is it:
unsigned int red = (hex << 8) >> 24;
commented: Interesting question. +6

Oh, you're right.

But actually, I dropped the system of using different members for red, green, blue, and alpha. I'm just using a single hex value as a member to save space.

Edit:
Just wondering, would this be any faster:

unsigned int red = (hex << 8) >> 16;
//or is it:
unsigned int red = (hex << 8) >> 24;

It would be the second one:

unsigned int red = (hex << 8) >> 24;

Which one is faster is a great question, one that I don't know the answer to but that hopefully others will.

Err... ok, ran into a prob again (like my first one). fyi ive gone back to the multiple member system (r,g,b,a as four separate variables). I still can't figure out how to let users pick whether or not to give the alpha bits. If they give (in a ARGB format) 0xee00ff00 (slightly transparent green), I'll read it fine, but if they give 0x00ff00, I'll read the alpha value as 0x00, when it should be 0xff. So my fix didn't really fix anything I guess. Any ideas on how to get this to work?

Think about 64-bit portability (why not?): hex << 8) >> 24 does not work if sizeof(unsigned int) > 4.
Make user input argument safety in 100% portable manner, for example:

rzb::color::color(unsigned int hex)
{
       m_alpha = (hex & 0xFF);
       m_blue   = ((hex>>=8) & 0xFF);
       m_green = ((hex>>=8) & 0xFF);
       m_red     = ((hex >>8) & 0xFF);
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.