User Tools

Site Tools


drawing_20a_20transparent_20bitmap

This is an old revision of the document!


Drawing a Transparent Bitmap

Introduction by Richard Russell

The commands built into BBC BASIC for Windows for displaying a bitmap image (*DISPLAY and *MDISPLAY) can only display an opaque image, i.e. anything 'underneath' the image will be obliterated. You may sometimes want to display a transparent image, that is one which has some regions in which you can see 'through' it to what lies beneath; you can do that using Windows GDI (Graphics Device Interface) API functions or BB4W library functions.

There are a number of different ways in which you can create and display a 'transparent' image:

  • Create the image as an icon (e.g. in the form of a .ICO file). An icon consists of two parts: a bitmap image and a mask; the mask is a one-bit-per-pixel bitmap determining which pixels of the image are opaque and which are transparent. You can create an icon in memory (e.g. CreateIcon API) or load it from a file (e.g. LoadIcon or LoadImage) and then display it using (e.g.) the Windows DrawIcon API or the SPRITELIB library.
  • Use a separate mask. As with the icon method, the mask consists of a one-bit-per-pixel monochrome bitmap (having the same dimensions as the image), determining which pixels of the image are opaque and which are transparent. You can display the resulting transparent bitmap using the MaskBlt API.
  • Define one of the colours in the bitmap image as 'transparent'; for example you could define all the 'black' pixels as being transparent. You can achieve that using the TransparentBlt function described in the main article below, or by means of the GFXLIB library.
  • Create the image as a 32-bits-per-pixel ARGB bitmap, in which each pixel consists of a 24-bit RGB value (8 bits red, 8 bits green, 8 bits blue) plus an 8-bit alpha value. The alpha value defines a 'per-pixel' opacity which can be anything from 0 (fully transparent) to 255 (fully opaque). You can display such a bitmap using the AlphaBlend API, by using the GDIplus or Direct3D subsystems, or by means of the GFXLIB library.
  • Create the image as a Transparent GIF or PNG and display it using, for example, the code listed here.


by Michael Hutton, July 2009

How do you make a part of a bitmap transparent? One way is to use the “TransparentBlt” function supplied in MSIMG32.DLL.

A complete example is here.

And an example bitmap you can use is here.
star.bmpstar.bmp


Explanation:

First select a MODE and define some constants:

      MODE 8
      REM!WC
      IMAGE_BITMAP = 0
      LR_LOADFROMFILE = &10
      DIM rect{l%,t%,r%,b%}
      cx% = 64 : REM width
      cy% = 64 : REM height

Next, we have to load the MSIMG32.DLL into memory and get the address of the “TransparentBlt” function.

      SYS "LoadLibrary", "MSIMG32.DLL" TO msimg32%
      SYS "GetProcAddress", msimg32%, "TransparentBlt" TO `TransparentBlt`

Next, load the image we want (we will assume it's in the same directory and is called star.bmp).

      bmpfile$ = @dir$ + "star.bmp"
      SYS "LoadImage", 0, bmpfile$, IMAGE_BITMAP, cx%, cy%, LR_LOADFROMFILE TO hbitmap%
      IF hbitmap% = 0 THEN ERROR 100,"Cannot Load Image."

Now, because we are using GDI and we only have a handle to the bitmap we have to create a new Device Context and select our bitmap into it. (A bitmap can only be selected into one DC at a time).

      SYS "CreateCompatibleDC", @memhdc% TO hdc%
      SYS "SelectObject", hdc%, hbitmap% TO old%


Now, we can ask GDI to transfer that bitmap into our main window. When using “TransparentBlt” we can select an RGB (COLOURREF) value to make transparent when it is drawing. It is the last parameter in “TranparentBlt”. Here I have selected 0 which is all the black bits (Red = 0, Green = 0, Blue = 0) but you can make it any colour you want. We also update a RECT{} so that we only update the region of the screen which has changed. It is much quicker to do this than update the whole window.

      FOR I% = 0 TO 50
        xpos% = RND(640)
        ypos% = RND(500)
        rect.l% = xpos%
        rect.r% = xpos% + cx%
        rect.t% = ypos%
        rect.b% = ypos% + cy%
        SYS `TransparentBlt`, @memhdc%, xpos%, ypos%, cx%, cy%, hdc%, 0, 0, cx%, cy%, 0
        SYS "InvalidateRect", @hwnd%, rect{}, 0
        WAIT 1
      NEXT


Now we must remember to cleanup all the GDI objects we have created otherwise we will end up with a leak.

      SYS "SelectObject", hdc%, old%
      SYS "DeleteDC", hdc%
      SYS "DeleteObject", hbitmap%
      SYS "FreeLibrary", msimg32%
      END


The example to copy and paste:

      MODE 8
      REM!WC
      IMAGE_BITMAP = 0
      LR_LOADFROMFILE = &10
      DIM rect{l%,t%,r%,b%}
      SYS "LoadLibrary", "MSIMG32.DLL" TO msimg32%
      SYS "GetProcAddress", msimg32%, "TransparentBlt" TO `TransparentBlt`
      cx% = 64
      cy% = 64
      bmpfile$ = @dir$ + "star.bmp"
      SYS "LoadImage", 0, bmpfile$, IMAGE_BITMAP, cx%, cy%, LR_LOADFROMFILE TO hbitmap%
      IF hbitmap% = 0 THEN ERROR 100,"Cannot Load Image."
      SYS "CreateCompatibleDC", @memhdc% TO hdc%
      SYS "SelectObject", hdc%, hbitmap% TO old%
      FOR I% = 0 TO 50
        xpos% = RND(640)
        ypos% = RND(500)
        rect.l% = xpos%
        rect.r% = xpos% + cx%
        rect.t% = ypos%
        rect.b% = ypos% + cy%
        SYS `TransparentBlt`, @memhdc%, xpos%, ypos%, cx%, cy%, hdc%, 0, 0, cx%, cy%, 0
        SYS "InvalidateRect", @hwnd%, rect{}, 0
        WAIT 1
      NEXT
      SYS "SelectObject", hdc%, old%
      SYS "DeleteDC", hdc%
      SYS "DeleteObject", hbitmap%
      SYS "FreeLibrary", msimg32%
      END


And there we are! Enjoy.

Michael Hutton

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
drawing_20a_20transparent_20bitmap.1522502357.txt.gz · Last modified: 2024/01/05 00:18 (external edit)