[SDL] Converting a surface to another color

David Olofson david at olofson.net
Sun Dec 31 21:52:41 PST 2006


On Sunday 31 December 2006 21:10, Viktor Dick wrote:
[...]
> Does anyone know how to change the color in a loaded surface?

The best way to properly "recolor" images is probably to convert from 
RGB to HSV, "rotate" H (Hue) and then convert back to RGB. 
Explanation and code:
	http://en.wikipedia.org/wiki/HSV_color_space
	http://www.cs.rit.edu/~ncs/color/t_convert.html


Or, just render the marbles from scratch...? Probably easier, and you 
get high quality scaling and various other parameters as a more or 
less free bonus. Oh, and you don't need any image files at all. ;-)

Here's some code from an old test program:
---------------------------------------------------------------
static SDL_Surface *create_sprite(int size, int aa, int trans)
{
        int x, y;
        SDL_Surface *s = SDL_CreateRGBSurface(SDL_SWSURFACE,
			size, size, 32,
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
                        0xff000000, 0x00ff0000, 0x0000ff00,
			0x000000ff);
#else
                        0x000000ff, 0x0000ff00, 0x00ff0000,
			0xff000000);
#endif
        if(!s)
                return NULL;

        for(y = 0; y < size; ++y)
                for(x = 0; x < size; ++x)
                {
                        unsigned char *p = s->pixels +
					y * s->pitch + x * 4;
                        float dx = x - size * 0.5;
                        float dy = y - size * 0.5;
                        float d = sqrt(dx*dx + dy*dy);
                        if(d > size * 0.5)
                        {
                                p[0] = 0;
                                p[1] = 0;
                                p[2] = 0;
                                p[3] = 0;
                        }
                        else
                        {
                                int v = (int)(255.0 *
						(1.0 - d / size * 2.0));
                                p[0] = v;
                                p[1] = v;
                                p[2] = v;
                                if(aa)
                                {
                                        if(v < 16)
                                                p[3] = v << 4;
                                        else
                                                p[3] = 255;
                                }
                                else
                                {
                                        if(v < 8)
                                                p[3] = 0;
                                        else
                                                p[3] = 255;
                                }
                                if(trans)
                                        p[3] /= 3;
                        }
                }
        return s;
}
---------------------------------------------------------------
Since this one renders a gray ball, you can modulate it by any RGB 
color you want by scaling 'v' before it's assigned to p[0], p[1] and 
p[2].


Another version, that does some funky color gradients - although this 
one's in EEL rather than C, but I guess you can figure out the maths 
anyway (same algorithm as the C code above):
---------------------------------------------------------------
import "SDL", "math";

export function render(size)
{
        local s = Surface[0, size, size, 32];   // Default masks
        local r = size / 2;
        for local y = 0, size - 1
        {
                local dy = (y - size / 2) / r;
                for local x = 0, size - 1
                {
                        local dx = (x - size / 2) / r;
                        local d = sqrt(dx*dx + dy*dy);
                        if ceil(d * r) == r
                                local a = 255 * (r - d * r);
                        else if d > 1
                                a = 0;
                        else
                                a = 255;
                        local c = MapColor(s, 255 - x * 255 / r,
                                        255 - y * 255 / r,
                                        d * 200,
                                        a);
                        Plot(s, c, x, y);
                }
        }
        return s;
}
---------------------------------------------------------------


//David Olofson - Programmer, Composer, Open Source Advocate

.-------  http://olofson.net - Games, SDL examples  -------.
|        http://zeespace.net - 2.5D rendering engine       |
|       http://audiality.org - Music/audio engine          |
|     http://eel.olofson.net - Real time scripting         |
'--  http://www.reologica.se - Rheology instrumentation  --'




More information about the SDL mailing list