This topic is 4633 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Probably one of those stupid allegro-questions, but here goes: http://www.systemsgo.se/masking/index.html I just need to know if it's possible and in any case how to have one bitmap (in my case a PNG-file with full alpha transparency - mostly for antialiasing-reasons) overlap another (any jpeg-file), thus masking the underlying content (the jpeg-file) resulting in a masked surface. (A basic feature found in Macromedia Flash for instance). In case I wasn't clear enough, I posted a graphic instance of what I want to achieve on the URL above. Just for further clarification, I want to use allegro with directX-support (so if I'm not mistaken, an openGL-solution - which probably won't be necessary in this case, won't work - right?)... Example code would be great! Best, John

##### Share on other sites
I don't realy know how alegro does stuff. But I would do it like this:

load both images replace the colors of the transparent one with the colors of the other (don't tuch the alpha) and your done. If you substract the colors of the transparent image you will get some some effects, but I don't think this is what you want to do.

##### Share on other sites
To be honest, I keep getting told Allegro can do this, but I've never seen it done in practice. You could probably write your own function to do this with the Allegro bitmaps, and if you're good it wouldn't even be that slow. [smile] If you want to use Allegro with DirectX, maybe try using DirectX to do this if that's easier, too. I've never tried DirectX though, so I won't comment.

##### Share on other sites
Is the PNG mask only used as a 1-bit black/white masking image? If so, you could use XOR drawing mode with rectfill to accomplish this.

I cannot tell by the images on the link you posted, but it looks like you want anti-aliased edges by what you said.

[Edited by - konForce on June 3, 2005 9:14:24 PM]

##### Share on other sites
Create an Allegro bitmap of depth 32 bits (create_bitmap_ex).

Then blit the solid bitmap into this memory bitmap.

Then copy the alpha channel from the other image - you might need to do this pixel by pixel, or there might be an Allegro blender function which just takes the alpha channel, or you could write your own.

Either way, this is a piece of precalculation that you only need to do once, or occasionally, right, so it doesn't matter if it takes a while.

Even for a big bitmap like this, it's still only going to take 100ms probably on a slowish machine, so it's not a problem provided you only do this once per level, or occasionally.

Mark

##### Share on other sites
Here is a demo that illustrates how to do it: mask.zip

In short, you need to:

• create a 32-bit bitmap for the RGBA image
• create an 8-bit bitmap for the mask. (Color #255 is 0% transparent, Color #0 is 100% transparent.)
• call set_write_alpha_blender() to enable the alpha layer writing
• use draw_trans_sprite() to apply the mask on top of the 32-bit RGBA image.
• call set_alpha_blender() to enable the alpha blitting
• use draw_trans_sprite() to draw the 32-bit RGBA picture to another bitmap, using the alpha layer to determine opacity.

It does exactly what you want to do, except that your PNG mask file needs to be replaced with an 8-bit image that represents the mask.

##### Share on other sites
Everyone - Seriously great! Thank you! - especially nefthy - looks great. I'll just optimize it for my needs and that's one less thing to worry about ;)

Again, big thanks!

##### Share on other sites
Updated question:
I'm currently testing things with the source code provided by nefthy... (available in the mask.zip above - or posted as text below)

Now, the question is: if I want to display a different background-image instead of the black which is produced by the mask-file (how do I do this?

In other words, still the same as before (circle reveals the yellow/orange picture, but instead of black surrounding, I want another image (lets say a sky-theme)... how?

_______________________________________

ORIGINAL SOURCE:

#include <allegro.h>

int main(void)
{
BITMAP *buffer; // screen buffer
int x = 0, y = 0; // coords of where to draw the mask
int k=0; // used for the key code
int mx,my; // old mouse x and y values

allegro_init();
set_color_depth(32);
set_gfx_mode(GFX_AUTODETECT_WINDOWED,800,600,0,0);
install_keyboard();
install_mouse();

buffer = create_bitmap(SCREEN_W, SCREEN_H);

// the image with alpha support *must* be 32-bit
// by default, this picture will be converted to 32-bit because
// that is what the current color depth is

// the mask needs to stay 8-bit, so we must disable color conversion
set_color_conversion(COLORCONV_NONE);

// set up initial mouse stuff
show_mouse(screen);
poll_mouse();
mx = mouse_x;
my = mouse_y;

do
{
// move mask coords with mouse
poll_mouse();
if (mx != mouse_x || my != mouse_y)
{
x = (mx = mouse_x) - mask->w / 2;
y = (my = mouse_y) - mask->h / 2;
}

set_write_alpha_blender(); // used for 'draw_trans_sprite()'
drawing_mode(DRAW_MODE_TRANS, NULL, 0,0); // used for 'rectfill()'

// set all the alpha values to 0 (transparent)
// this works because we set the drawing mode to DRAW_MODE_TRANS
rectfill(pic, 0,0,pic->w,pic->h, 0);

// update the alpha values based on the image mask
// this works because we enabled the "write alpha blender"

// reset the drawing mode to solid and draw a rectangle around the image
drawing_mode(DRAW_MODE_SOLID, NULL, 0,0);
clear(buffer);
rect(buffer, 0,0, pic->w+1, pic->h+1, makecol(255,255,255));

// set the blender to alpha drawing
set_alpha_blender();
draw_trans_sprite(buffer, pic, 1,1); // draw the picture with its alpha

// blit buffer to screen
blit(buffer, screen, 0,0, 0,0, SCREEN_W, SCREEN_H);

// move the mask coords with keys
if (keypressed())
{
if (k == KEY_LEFT) x--;
if (k == KEY_RIGHT) x++;
if (k == KEY_UP) y--;
if (k == KEY_DOWN) y++;
}
} while (k != KEY_ESC && !mouse_b);

destroy_bitmap(buffer);
destroy_bitmap(pic);
return 0;
}
END_OF_MAIN()

##### Share on other sites
Quote:
 In other words, still the same as before (circle reveals the yellow/orange picture, but instead of black surrounding, I want another image (lets say a sky-theme)... how?

You need to blit the sky theme to the buffer before drawing the alpha sprite to the buffer.

// reset the drawing mode to soliddrawing_mode(DRAW_MODE_SOLID, NULL, 0,0);clear(buffer);// blit the sky-theme image to the bufferblit(sky, buffer, 0,0, 0,0, sky->w,sky->h);// set the blender to alpha drawingset_alpha_blender();draw_trans_sprite(buffer, pic, 1,1); // draw the picture with its alpha

##### Share on other sites
Thx! works perfectly...

one more thing I can't figure out: I can define the X and Y coordinates of both the mask and the sky-theme - but I can't figure out how to define the X and Y of the image shown through the mask (in my case the orange/yellow image).

Let's say I want to displace this (nudge it upwards along the Y-axis about 40 pixels), without displacing the sky-image (let's call this the background image) or the mask itself.

is there some ...0,0 (x,y)... I have yet to define to do this?

Note that this may seem trivial using the images, etc I've posted as example-files in the beginning of this thread - but is vital to the effect itself, using multiple maskinglayers and other images.

##### Share on other sites
If you want to show a different part of the Alpha image, then you need to adjust the x,y values of:

This will put the mask at a different location, causing a differnet part of the picture to show.

If you want to put the alpha picture itself at a different location, then just adjust the x,y values of:

draw_trans_sprite(buffer, pic, x,y);

If you always draw the background picture (sky, etc) at 0,0 of the buffer, then moving the x,y in the above draw_trans_sprite() will cause the alpha picture to move around relative to the background.

##### Share on other sites
Heh... tried that same thing yesterday but for some strange reason (probably lack of sleep) is wouldn't work then. Today however, grand success ;) Thanks!

One more thing however: right now, every image and mask used is .bmp-files (32-/24- or 8-bit). Well... that's great, since everything works great, only: bmp's take a lot of diskspace compared to lets say jpegs...

... so how do I use for instance jpegs (and/or PNG-files) to do the same thing in this code? i downloaded libJPEG and linked the libJPEG.dll.a to the project - but just exchanging the .bmp to .jpg in code (and of course new jpeg-images in the dir), just didn't to it.

Help...?

##### Share on other sites
You need an interface library that works with Allegro.

For JPEG files you can use: JPGAlleg

For PNG Files you can use LoadPNG. (Also requires libPNG and zlib/)