displaying transparent .bmp

Started by
4 comments, last by ageny6 20 years, 8 months ago
Of what I am aware, only MaskBlt in the windows GDI will blt a bitmap with a transparent background, but it requires a mask. Is there a way to display a bitmap with a transparent background without utilizing a mask image? Jonathan
My signature used to suck. But it's much better and more accurate now.
Advertisement
There are different ways of displaying BMPs with transparency. But they all need that you get access to the bits area of your buffer, except the 4th method which is library specific.
Your algorithm would then become:
1 - copy bitmap data to the buffer using proprietary algo.
2 - blit the buffer to the screen.
To be able to implement the other ways, your buffer should be created as a DIBSection:
- you have access to the bits area so you can perform any special effects
- it is easily and quickly blitted to the screen by the GDI Blit function.

OK, now to the different methods:
1- the simplest: you copy your bitmap data checking every pixel for transparent colors. It can be optimized: if you have a 16bit depth bitmap you can check for each DWORD. You need to handle 4 cases:
tt -> no draw
tc -> advance 1 pixel in buffer area and draw 1 pixel
ct -> draw 1 pixel and advance 1 pixel in buffer area
cc -> memcopy 2 pixels
2- memory compressed bitmaps: you store only colour area of your bitmap and you compress the transparent area. So if you have a bitmap like tttttccccttccttt, it is encoded as 5t4cccc2t2cc. When you draw you just test for the color: if transparent advance n pixels in buffer area else memcopy n pixels.
3- coded bitmaps: the bitmap drawing is in the code. You do not need anymore to load bitmaps, they are part of your code: you have as many draw functions as you have bitmaps.
4- using a drawing library (DirectDraw or OpenGL): you load up your bitmap, declare the transparent color not to be drawn and let the library handle the blitting for you.

The methods most often used are the 2nd (memory compressed bitmaps) when you are under GDI alone and the 4th (drawing library) when you use a 3rd party library like DirectX or OpenGL.

Hope that helps.
Ghostly yours,
Red.
Ghostly yours,Red.
the method most used to blit transparently via GDI is to use a mask. doing any sort of GDI-based blitting on a pixel by pixel basis is about as slow as you can get and is typically only done when alpha-blending is wanted on platforms that nativaly lack support for it. on 9x you simply create your own mask. on NT-based platforms you can use MaskBlt if you want. you can also get transparent blitting if you convert the bitmap to an icon and then use DrawIcon/Ex, but these use a mask behind the scenes. you can also use imagelists but again they use masks behind the scenes. there''s also TransparentBlt and AlphaBlend as well as UpdateLayeredWindow if you want to alpha-blend to the desktop but those are generally only available on 2K and XP. there''s also GDI+ images/bitmaps which will allow color keyed and alpha-blended blitting. that''s available on 2K and XP by default and as a redistributable on 9x (not ''95 though i think.)
How exactly do you create a DIB bitmap? I know that to create a device compatible bitmap you must:<br>1) Call CreateCompatibleDC(GetDC(0)) to find a DC<br>2) Call SelectObject using the DC created in step 1 and load the image desired from file. <br><br>For example, the code would look as follows:<br>TMPDC = CreateCompatibleDC(GetDC(0))<br>SelectObject TMPDC, LoadImage(0, ImagePath, 0, width, height, LR_LOADFROMFILE)<br><br>Are the steps the same for DIB bitmap but with different parameters?<br><br>In an attempt to figure this out myself, I looked at the MSDN Library and fell &#111;n this function called CreateDIBSection. I am a bit confused &#111;n the parameters of the function and am not totaly sure of proper neccesitied use (how to use it with other code to properly create the DIB Bitmap). The parameters are as follows:<br><br>HBITMAP CreateDIBSection(<br> HDC hdc, // handle to device context<br> CONST BITMAPINFO *pbmi,<br> // pointer to structure containing bitmap size, <br> // format, and color data<br> UINT iUsage, // color data type indicator: RGB values or <br> // palette indexes<br> VOID *ppvBits, // pointer to variable to receive a pointer to <br> // the bitmap''s bit values<br> HANDLE hSection, // optional handle to a file mapping object<br> DWORD dwOffset // offset to the bitmap bit values within the <br> // file mapping object<br>); <br><br>What exactly does the function require for iUsage, *ppvBits, hSection, and dwOffset? How do I use this function to create the DIB Bitmap?<br><br>Thanks <br><br>Jonathan
My signature used to suck. But it's much better and more accurate now.
To AP:
Regarding methods proposed, I tend to be very conservative of my memory since I am used to programming on Win 9x. This is why I favor the 2nd method under GDI alone. The GDI is really good at straight blitting, but if I want to optimize my blitting to avoid redrawing twice or thrice on the same area, I need to have an access to bitmap bits (using light length compressed bitmaps and having a c-buffer to track coverage of your screen).

To ageny6:
A DIB is a device independant bitmap. CreateDIBsection creates a DIB that applications can write to directly (quoting from the win32 programmer''s reference).
The steps are almost the same to set up:
1 - CreateCompatibleDC to get a DC compatible with your screen capabilities.
2 - Fill in a BitmapInfoHeader setting the characteristics of your buffer
3 - Call CreateDIBSection with the Compatible DC you got, the BitmapInfoHeader you filled in, DIB_RGB_COLORS to tell windows your bitmap is an array of RGB colors, you also need to provide a pointer to the location of the bits area of your DIB, NULL and NULL

This returns a handle to your DIB: I use it as a buffer. You can use it to draw on it either by blitting bitmaps on it with the functions proposed by AP, or by directly memcopying bitmap bits data to the bits area of your DIBSection. When you have finished drawing, you blit the DIBSection to the screen.

If you check the Articles and Resource section you will find many insights on bitmap blitting. Besides a google search on bitmap blitting will get you a lot of litterature on the subject.

Hope that helps.
Ghostly yours,
Red.
Ghostly yours,Red.
if speed is a concern, you might want to look into the DrawDib functions. they bypass the GDI and go straight to video memory from the DIB memory.

a nice little MFC class which encapsulates drawing with GDI DIBs can be found at http://www.codeguru.com/bitmap/ebgfx.shtml. it can easily be converted to non-MFC if you''re going win32 only.

This topic is closed to new replies.

Advertisement