PDA

View Full Version : Blitting transparent 8bit images with TransparentBlt



andy
26-02-2008, 09:53 PM
Greetings,
I'm working with 8bit bitmap to display old game graphics (sprite, background, ecc.) on a TImage; simple GDI, no DirectX.
The TransparentBlt function work very well with transparency, but only when the transparent color is 0 (the first index of palette array).

TransparentBlt(Image1.Canvas.Handle, x, y, Bitmap.Width, Bitmap.Height,
Bitmap.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height,
0);
work well with an 8bit bitmap which have the 0 index color transparent, for any other color (for ex. 255), do not work, it will display the transparent color as solid.
Any suggestion? Can be a bug of TransparentBlt? Am I wrong with something?

Meanwhile, I've created an "old-style" routine (I come from the old DOS Pascal 13h gfx world):

Var SrcLine, DstLine: PByteArray;

Image1.Picture.Bitmap.PixelFormat := pf8bit;
Image1.Picture.Bitmap.Palette := CopyPalette(Bitmap.Palette);
for i := 0 to Bitmap.Height - 1 do
begin
SrcLine := Bitmap.ScanLine[i];
DstLine := Image1.Picture.Bitmap.ScanLine[i];
for j := 0 to Bitmap.Width - 1 do
begin
pixel_color := SrcLine[j];
if pixel_color <> 255 then
DstLine[j] := pixel_color;
end; //for j
end; //for i
Not so faster, but work (and for eliminate flicker, I can use a back buffer bitmap).
Any speed-up suggestion? Asm?

cronodragon
27-02-2008, 03:57 AM
work well with an 8bit bitmap which have the 0 index color transparent, for any other color (for ex. 255), do not work

I have no experience with that function, but I have used paletted bitmaps (the old VGA days). Checking that function's reference it says this about the transparent color:


crTransparent
[in] The RGB color in the source bitmap to treat as transparent.

It's probably expecting the 3 components Red, Green and Blue enconded inside an UINT (Delphi's Longword type), not the palette index as you seem to be passing from your example "(for ex. 255)". The reason it's working with index 0 might be because the palette has black color in the first index of the palette, so you think it's refering to that index, but the function is decoding the 0 ($00000000) as Red:0, Green:0, Blue:0, so it's just a coincidence :)

I found a nice application with source that should help you:
http://www.efg2.com/Lab/Graphics/Colors/PaletteLab.htm

andy
27-02-2008, 02:11 PM
It's probably expecting the 3 components Red, Green and Blue enconded inside an UINT (Delphi's Longword type), not the palette index as you seem to be passing from your example "(for ex. 255)". The reason it's working with index 0 might be because the palette has black color in the first index of the palette, so you think it's refering to that index, but the function is decoding the 0 ($00000000) as Red:0, Green:0, Blue:0, so it's just a coincidence Smile
thanks for your reply, I was fears that; of course is impossible always use the RGB, because, in 8bit bitmap, sometime the same color is used in two different index (0 and 31 for ex.), so if I make transparent the RGB color and not the index, I make transparent also the other color that must be solid.
I must make transparent only the index, not the RGB.

However, I've tried the function using the RGB of the color... but seem not working, work only with color 0, that's very strange. If I've time I'll make some example program.


I found a nice application with source that should help you:
http://www.efg2.com/Lab/Graphics/Colors/PaletteLab.htm
I know that site, it was my first reference :)