Sign in to follow this  

Dynamic creation of bitmap masks

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey all, I'm trying to create a mask dynamically from a bmp image. Everything I'm doing here gets stored to a struture that looks like this:
struct GraphicStruct
    {
    HBITMAP Graphic;
    HBITMAP Mask;
    int Width;
    int Height;
    };

I load this up like so:
    //the race icons (10 of these)
    LoadBitmap("MaleHuman", &MaleHuman);
    CreateBitmapMask(&MaleHuman, NULL, 0, 0);

The first function (LoadBitmap) loads Graphic, Width, and Height of the structure, and this works fine (I've checked it quite extensively and there is no problem with it). The second function is meant to create the Mask part (and modifies the original bitmap Graphic slightly to work with the mask). Here is the routine:
void MainScreenClass::CreateBitmapMask(GraphicStruct *Bitmap, COLORREF TransColor, int TransPixelX, int TransPixelY)
    {
    BITMAP bm;
    HDC Src;
    HDC Dst;
    COLORREF Trans;
    COLORREF SaveBk;
    COLORREF SaveDstText;
    HBITMAP SrcT;
    HBITMAP DstT;

    //Get the dimensions of the source bitmap
    GetObject(Bitmap->Graphic, sizeof(bm), &bm);

    //Create the mask bitmap
    DeleteObject(Bitmap->Mask);
    Bitmap->Mask = CreateBitmap(bm.bmWidth, bm.bmHeight, 1, 1, NULL);

    //We will need two DCs to work with. One to hold the Image
    //(the source), and one to hold the mask (destination).
    Src = CreateCompatibleDC(NULL);
    Dst = CreateCompatibleDC(NULL);

    //Load the bitmaps into memory DC
    SrcT = (HBITMAP)SelectObject(Src, Bitmap->Graphic);
    DstT = (HBITMAP)SelectObject(Dst, Bitmap->Mask);

     //Dynamically get the transparent color
     if (TransColor == NULL)
        Trans = GetPixel(Src, TransPixelX, TransPixelY);
     else
        Trans = TransColor;

    //Change the background to trans color
    SaveBk  = SetBkColor(Src, Trans);

    //create the monocrome mask bitmap
    BitBlt(Dst, 0, 0, bm.bmWidth, bm.bmHeight, &Src, 0, 0, SRCCOPY);

    //Now, we need to paint onto the original image, making
    //sure that the "transparent" area is set to black.
    SaveDstText = SetTextColor(Src, RGB(255,255,255));
    SetBkColor(Src, RGB(0,0,0));
    BitBlt(Src, 0, 0, bm.bmWidth, bm.bmHeight, &Dst, 0, 0, SRCAND);

    //Clean up by deselecting any objects, and delete the DC's.
    SetTextColor(Dst, SaveDstText);

    SetBkColor(Src, SaveBk);
    SelectObject(Src, SrcT);
    SelectObject(Dst, DstT);

    DeleteDC(Src);
    DeleteDC(Dst);

    return;
    }

Finally, I'm checking this out by drawing to the screen, like so:
    HDC Graphic;
    HDC Mask;
    int Width;
    int Height;

    //test the graphics to make sure they exist and look right
    Graphic = CreateCompatibleDC(hdc);
    Mask = CreateCompatibleDC(hdc);

    SelectObject(Graphic, MaleHuman.Graphic);
    SelectObject(Mask, MaleHuman.Mask);
    Width = MaleHuman.Width;
    Height = MaleHuman.Height;

    BitBlt(hdc, 200, 100, Width, Height, Graphic, 0, 0, SRCCOPY);
    BitBlt(hdc, 200, 200, Width, Height, Mask, 0, 0, SRCCOPY);

    BitBlt(hdc, 200, 300, Width, Height, Mask, 0, 0, SRCAND);
    BitBlt(hdc, 200, 300, Width, Height, Graphic, 0, 0, SRCPAINT);

    ......

    DeleteDC(Graphic);
    DeleteDC(Mask);


The first two blits are straight copys just for testing purposes, to make sure the graphics are really there and look right. The final two blits are meant to show the graphic with transparency. The end result of all of this is that the first blit works (sort of). The original graphic is there, but it has NOT been modified by the mask creation routine to set the transparency color to black. The second blit is more disturbing. The bitmap is there, but it is completely black, there is no white on it at all (it is, however, the correct size). Of course, the third icon (from blits 3 and 4) is appearing exactly as the first with no transparency at all (presumably due to the fact that no white appears on the mask). So: Why is my "CreateBitmapMask" failing to do anything except create a mask and set it to 0? Why does the same routine not replace the "hot pink" color I am using as my transparency color with black on the original graphic? What am I doing wrong here? I'm not so experienced in dealing with Win32 blitting, this is kind of a new area for me :) Ron

Share this post


Link to post
Share on other sites
Nevermind, I figured it out. It never fails, I can stare at a routine for four hours and not find the bug, then two minutes after I post looking for help, I discover the problem.

I had an extraneous '&' in both the BitBlt routines in the CreateBitmapMask routine. Works fine now.

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this