Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Color Condundrum

This thread is locked; no one can reply to it. rss feed Print
Color Condundrum
nshade
Member #4,372
February 2004

Ok, here's an interesting thing to ponder.

I porting a game that originally had 16 colors, but had some spiffy color functions I'm trying to duplicate in Allegro 5 with 24 bit color.

The prototype that I'm currently trying to implement is thus:

void DoColorMask(int d, int s, int dx, int dy, int sx, int sy, int w,int h, int col);

d - destination bitmap
s - source bitmap
dx - destination x
dy - destination y
sx - source x
sy - source y
w - source width
h -source height
col - color

The function was a poor man's "tint" function, and behaves a little like al_draw_tinted_bitmap_region().... Kind of

The is how the DoColorMask() function works:
While the source bitmap region is pixel-for-pixel copied to the destination, it will check the color of the pixel being copied. If the pixel isn't black, then change the pixel color to "col". This means that if you have a solid red colored button with black text, you can use the function to make the button white with black text.

I've been doing some experiments with al_draw_tinted_bitmap_region() that's promising, except there are issues I'm not sure how to resolve yet.

This was an experiment that was generated with the following code.

//white
  al_draw_tinted_scaled_bitmap(test, al_premul_rgba_f(1, 1, 1, 1), 0, 0, 1024, 768, 0, 0, 512, 384, 0);  //normal
  //red
  al_draw_tinted_scaled_bitmap(test, al_premul_rgba_f(1, 0, 0, 1), 0, 0, 1024, 768, 512, 0, 512, 384, 0);
  al_draw_tinted_scaled_bitmap(test, al_premul_rgba_f(1, 1, 1, .5), 0, 0, 1024, 768, 512, 0, 512, 384, 0); //normal
  //green
  al_draw_tinted_scaled_bitmap(test, al_premul_rgba_f(0, 1, 0, 1), 0, 0, 1024, 768, 0, 384, 512, 384, 0);
  al_draw_tinted_scaled_bitmap(test, al_premul_rgba_f(1, 1, 1, .5), 0, 0, 1024, 768, 0, 384, 512, 384, 0); //normal
  //blue
  al_draw_tinted_scaled_bitmap(test, al_premul_rgba_f(0, 0, 1, 1), 0, 0, 1024, 768, 512, 384, 512, 384, 0);
  al_draw_tinted_scaled_bitmap(test, al_premul_rgba_f(1, 1, 1, .5), 0, 0, 1024, 768, 512, 384, 512, 384, 0); //normal

Upper left is the "normal" color bars, upper right is red tint, lower left is green tint and lower right is blue tint

What I did was lay down the color channel I wanted for tint and then overlayed the "normal" color at 50% alpha. This is a good 24 bit color approximation of what I'd like to do, but I have two problems.

1) I can't turn anything "white" just a tint of color. Overlying a full color channel with a full color alpha results in the same color.

2) I can't make a color brighter then it's base, for the same reason above.

Now what I really need is a function that duplicates GIMP's "Colorize" function. (you can see an example of this function here.) How that works is that you give it a picture, and it will strip everything out but the luminosity channel (Makes it black and white). Then it applies a color tint to that channel. From there you adjust three sliders for Hue, Saturation, and Lightness.

Any ideas on how to apply that concept to Allegro? How would you convert a bitmap to just B&W, and after you do that when you apply the hue, it shouldn't effect black or white. (Unless I change the lightness) For example, if I was to use al_draw_tinted_bitmap_region() that would make the white tint to that color like the above, right That's not what I want.

Bonus:

I don't know what a "shader" is other then a thingy in my GPU that makes special effects. As the program is going to be cross platform anyway, assume that using a "shader" is off the table.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I'm not quite sure what you're trying to achieve.

nshade said:

The is how the DoColorMask() function works:
The while the source bitmap region is pixel-for-pixel copied to the destination, it will check the color of the pixel being copied. If the pixel isn't black, then change the pixel color to "col". This means that if you have a solid red colored button with black text, you can use the function to make the button white with black text.

I understand what you mean when you say colorize, but every color that's not black?

How often do you need this effect? Is it on every frame? Or can you do it once?

You'll probably want to check out al_set_blender and al_set_separate_blender.

If you want to 'tint' a bitmap white, you need to draw the white over the top with varying alpha.

You can lock a bitmap region with al_lock_bitmap and change the data, but you'll probably need a shader if you want real time colorization.

nshade
Member #4,372
February 2004

The function is most often used used to "flash" buttons a different color when you click it. Keep in mind this program doesn't use "frames" in the modern sense. It updates parts of the screen arbitrarily because it's largely a GUI. For example, when it flashes a button, it doesn't render the whole screen on a backbuffer with updated data and flips. It copies the button from the screen, updates the color, and then puts it back. (Then it waits about a tenth of a second, colors it back to the original color, an then repeats for about 5 flashes) all without flipping a page.

I updated the code so the backbuffer is a little more sane. Now it will flip when display is altered, but I'm kind of a slave the machine states.

Is there a slick way you can make a color bitmap black and white maybe. I mean short of doing a X,Y for loop and changing every pixel. I can assume it gets a little slow with a 1280x800 array.

Elias
Member #358
May 2000

There is no way to make it black and white except for shaders or going through the pixel data.

The imgur picture is not clear to me, which part is the original picture? Can you maybe post your original picture, then the effect you want (from gimp I suppose), and the effect you currently get?

--
"Either help out or stop whining" - Evert

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

What you're asking for is a mask color and color replacement. I don't think you can do that with a blender alone. Elias is right, you will need to process the pixel data yourself, either through a lock or a shader.

However, what you can do is take a black and white image and colorize the white portion. It would mean changing all your graphics, but it would be more flexible. However, I can't believe all your art is simply monochrome, and I think you're asking to replace only certain colors with the 'tint' color. What you're doing there is altering the hue and saturation.

Go to: