Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I usually use an <code>union</code>:</p> <pre><code>union color { unsigned int value; unsigned char component[4]; }; color c; c.value = 0xAABBCCFF; unsigned char r = c.component[0]; unsigned char g = c.component[1]; unsigned char b = c.component[2]; unsigned char a = c.component[3]; </code></pre> <p>If you need to treat it as a float value:</p> <pre><code>float fr = c.component[0] / 255.0f; float fg = c.component[1] / 255.0f; float fb = c.component[2] / 255.0f; float fa = c.component[3] / 255.0f; </code></pre> <p>EDIT:</p> <p>As mentioned in the comments below, this use of <code>union</code> is Undefined Behaviour (UB), see <a href="https://stackoverflow.com/questions/11373203/accessing-inactive-union-member-undefined">this question</a> from <a href="https://stackoverflow.com/users/673730/luchian-grigore">Luchian Grigore</a>.</p> <hr> <p>EDIT 2:</p> <p>So, another way to break a <code>DWORD</code> into components avoiding the <code>union</code> is using some bitwise magic:</p> <pre><code>#define GET_COMPONENT(color, index) (((0xFF &lt;&lt; (index * 8)) &amp; color) &gt;&gt; (index * 8)) </code></pre> <p>But I do not advise the macro solution, I think is better to use a function:</p> <pre><code>unsigned int get_component(unsigned int color, unsigned int index) { const unsigned int shift = index * 8; const unsigned int mask = 0xFF &lt;&lt; shift; return (color &amp; mask) &gt;&gt; shift; } </code></pre> <p>How it works? Lets supose we call <code>get_component(0xAABBCCFF, 0)</code>:</p> <pre><code>shift = 0 * 8 shift = 0 mask = 0xFF &lt;&lt; 0 mask = 0x000000FF 0x000000FF &amp; 0xAABBCCFF ---------- 0x000000FF 0x000000FF &gt;&gt; 0 = 0xFF </code></pre> <p>Lets supose we call <code>get_component(0xAABBCCFF, 2)</code>:</p> <pre><code>shift = 2 * 8 shift = 16 mask = 0xFF &lt;&lt; 16 mask = 0x00FF0000 0x00FF0000 &amp; 0xAABBCCFF ---------- 0x00BB0000 0x00BB0000 &gt;&gt; 16 = 0xBB </code></pre> <p><em>Warning! not all color formats will match that pattern!</em></p> <p>But IMHO, the neater solution is to combine the function with an enum, since we're working with a limited pack of values for the index:</p> <pre><code>enum color_component { A,B,G,R }; unsigned int get_component(unsigned int color, color_component component) { switch (component) { case R: case G: case B: case A: { const unsigned int shift = component * 8; const unsigned int mask = 0xFF &lt;&lt; shift; return (color &amp; mask) &gt;&gt; shift; } default: throw std::invalid_argument("invalid color component"); } return 0; } </code></pre> <p>The last approach ensures that the bitwise operations will only be performed if the input parameters are valid, this would be an example of usage:</p> <pre><code>std::cout &lt;&lt; "R: " &lt;&lt; get_component(the_color, R) / 255.0f &lt;&lt; '\n' &lt;&lt; "G: " &lt;&lt; get_component(the_color, G) / 255.0f &lt;&lt; '\n' &lt;&lt; "B: " &lt;&lt; get_component(the_color, B) / 255.0f &lt;&lt; '\n' &lt;&lt; "A: " &lt;&lt; get_component(the_color, A) / 255.0f &lt;&lt; '\n'; </code></pre> <p>And here is a <a href="http://ideone.com/xvu7np" rel="nofollow noreferrer">live demo</a>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload