GTK+ Forums Forum Index GTK+ Forums
Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

convertRGBtoPixel

 
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Example Code
Author Message
William J Giddings
Familiar Face


Joined: 17 Jan 2010
Posts: 46

PostPosted: Mon Feb 15, 2010 10:19 am    Post subject: convertRGBtoPixel Reply with quote

After Tad supplied the magic ingredient (thanks) to get the right values to get the GdkPixbuf fill function to behave properly, I felt it only right to share the result with my fellow users as there may be others stratching large chunks out of their heads trying to solve this for themselves.

The function below will accept any usual rgb colour string, e.g. 'red', 'blue', '#223344' and return the appropriate format for the guint32 required by for fill operations. I can't say that I fully understand how this works, but it does.

WJG

Code: (Plaintext)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
\brief    Convert colours in string form to guint32
\author   Tadej Borovšak, William J Giddings
\date     14/Feb/10
\since    0.9.94
**/
static guint32 convertRGBtoPixel ( gchar *clr )
{

GdkColor color;
guint32 pixel;

/* Conversion factor from 16-bit color to 8-bit color (0xff / 0xffff) */
const gdouble f = 0.00389105;

/* create the colour from the supplied string, added by WJG */
gdk_color_parse ( clr, &color );

/* fill with colour */
pixel = ( ( ( guint ) ( color.red * f + 0.5 ) ) << 24 ) | /* R */
( ( ( guint ) ( color.green * f + 0.5 ) ) << 16 ) | /* G */
( ( ( guint ) ( color.blue * f + 0.5 ) ) << 8 ) | /* B */
( 0xff << 0 ); /* A */
return pixel;
}
Back to top
tadeboro
Never Seen the Sunlight


Joined: 23 Jul 2008
Posts: 2132
Location: Slovenia

PostPosted: Tue Feb 16, 2010 11:44 am    Post subject: Reply with quote

Hi.

I'll explain things a bit more, since William was kind enough to write down this code.

First important thing in this code is conversion factor. GdkColor stores color components as unsigned 16-bit entities, which means that each component can have value in interval [0, 65535]. Pixel value on the other hand uses 8-bits per color component, which means that component can have value in interval [0, 255]. Calculating conversion factor is simple now:
Code: (Plaintext)
1
2
3
                                      8-bit max value
8-bit component = 16-bit component x ----------------
                                     16-bit max value
In real code, 0.5 is added to calculated 8-bit value to accommodate conversion from floating point number to integer type.

Second important thing is bit shifting. Pixel is defined as 32-bit entity, with 8-bits per component. Schematically, pixel looks like this for different colors:
Code: (Plaintext)
1
2
3
4
5
| red  | |green | | blue | |alpha |
00000000 00000000 00000000 00000000 fully transparent black
11111111 00000000 00000000 11111111 fully opaque red
00000000 11111111 00000000 01111111 50% transparent green
00000000 00000000 11111111 10010110 41% transparent blue

You can see that we need to shift red component 24 bits to the left in order to position it properly, green component 16 bits, blue 8 bits and alpha 0 bits. Finally, to combine them all together, we need to use bitwise or and we're done.


For sake of completeness, let's convert a color with HTML notation #3489ae using William's function and monitor progress step-by-step.

gdk_color_parse() function will return components like this (I won't explain how this is done, since GDK will do this for you):
Code: (Plaintext)
1
2
3
4
red   = 13364 (0x3434)
green = 35209 (0x8989)
blue  = 44718 (0xaeae)
(Note: Notice anything interesting when comparing calculated values with input?)

Now we reduce precision of color components by converting them from 16-bit to 8-bit numbers and adding fully opaque alpha value. What we get is:
Code: (Plaintext)
1
2
3
4
5
red   = 52  (0x34)
green = 137 (0x89)
blue  = 174 (0xae)
alpha = 155 (0xff)
(Note: Again, interesting values, do you agree?)

This is how these values look in binary, expressed as 32-bit entities:
Code: (Plaintext)
1
2
3
4
red   00000000 00000000 00000000 00110100
green 00000000 00000000 00000000 10001001
blue  00000000 00000000 00000000 10101110
alpha 00000000 00000000 00000000 11111111

And this is what we get after bit shifting and applying bitwise or:
Code: (Plaintext)
1
2
3
4
5
6
red   00110100 00000000 00000000 00000000
green 00000000 10001001 00000000 00000000
blue  00000000 00000000 10101110 00000000
alpha 00000000 00000000 00000000 11111111
-----------------------------------------
pixel 00110100 10001001 10101110 11111111

And we're done.

Tadej
Back to top
Display posts from previous:   
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Example Code All times are GMT
Page 1 of 1

 


Powered by phpBB © 2001, 2005 phpBB Group
CodeBB 1.0 Beta 2
Protected by Anti-Spam ACP