Mega Code Archive

 
Categories / Delphi / Graphic
 

Working with Colour and Colour Blending

Title: Working with Colour and Colour Blending I have been asked the question of how to use and/or blend colours often, and on this forum it has been asked many times and there seems to be not much info readily available here, so I tried to make a short information piece that may hopefully help some new programmers to understand colour, colour intensities and colour blending better. This piece have been posted as a response on the forum and subsequently I've been asked to put it under this "tips" section - which I now oblige. I hope some of you find this helpful. Enjoy. (Pardon the English spelling, of course on the PC it is spelt "Color" and not "Colour" - even Borland ain't perfect :D). Colour on a computer screen are created by mixing light intensities of the 3 basic light colours: Red, Green and Blue. You can assign any colour to a colour capable component by specifying a 32-bit integer constant that has 4 bytes (0-g-b-r). The first byte is 0 (for pallette selection, like CMYK etc.), but on-screen colours just use 0, then 1 byte each for the Green, Blue and Red relative intensities. The whole integer looks like this in hex format: Color := $00GGBBRR; (We will use the $ as a hexadecimal denotion here like in Delphi). A screen card and driver that can effectively display a different hue for every one of the 256 intensities per colour band (Red, Green, Blue) is said to operate in "TrueColor mode". This usually is 32-bit (4-byte) or 24-bit (3-byte), where 24-bit is the same as 32-bit without the palette byte but also with 256 intensities per colour band. Lesser modes (like 16-bit and 256-colour mode) rounds your colour settings to the nearest available colour and sometimes use dithering (mixing pixels to one hue below and and hue above the required colour). When working with colouring algorithms, it helps to have your screen set to the highest available scheme, preferably 32 or 24 bit so that your colour results are accurate when viewed. if I want a dark red color, I can use $00000080 (the RR section at $80 which is about half the full intensity of $FF). A very intense red would then be $000000FF, similarly a very intense Green would be $00FF0000. To break a colour into it's components, we use GetGValue, GetBValue and GetRValue (from Windows API) and to combine the 3 colours into 1 color we use the RGB function. See code at bottom for details. Now, we have many options for blending 2 colours, we could simply add the r,g,b components together, but this regularly produces new colours of no significance and over intensity, for instance, if I blend blue and red ($0000FF00 and $000000FF) then I end up with a Fuchsia colour ($0000FFFF) of which the total intensity is much brighter than any of the original colours. The best method is mean blending where we average the intensities with the total intensity no more than 1.5 times the highest individual component total intensity. This is sometimes referred to as Alpha blending, though true Alpha blending is done according to an intensity map, which is a bitmap with 1 byte for each pixel specifiying the intensity of the primary and secondary color in that point. If the Alpha for the color is given as $80 (50%) then the colours are mixed equal, if it is $FF then we fully use the Primary colour and for $00 we fully use the secondary colour, and for $40 (25%) we use 25% intensity Primary colour and 75% intensity secondary etc. Note on intensity: If you have a colour defined as $00804000 and want to raise the light intensity (brightness), you simply add the same value to each colour, like adding 5 intensity in the above case we find a new colour (of exactly the same hue, but 5 intensity points brighter): $00854505. The same goes for dimming a colour, subtract the same amount from each of r, g and b. The total values of the r, g and b components defines the intensity, and the relationship (differences) between them defines the color Hue. Below are some blending functions I've made. I've used the totalizing, averaging, a pseudo "Alpha" blending and a true Alpha blending to demonstrate some simple ways of blending 2 colors. Since the first post some other forum contributors have added to these functions (thank you all), I post all of them here. Please not that these functions have been written with ease of understanding in mind and not execution-speed. I'm sure many of you will immediately notice the possible speed/efficiency enhancements and I urge you to improve where possible. At the bottom I've put some interesting observations on colour, but without further delay, here's the colour blending functions: