Image Transparency Routine

This is a discussion on Image Transparency Routine within the Windows Programming forums, part of the Platform Specific Boards category; Hello, I need help with making my own transparent image routine. Basically, I need to be able to render semi-transparent ...

  1. #1
    Registered User
    Join Date
    Apr 2009
    Posts
    45

    Image Transparency Routine

    Hello,
    I need help with making my own transparent image routine. Basically, I need to be able to render semi-transparent images on screen using C++... TransparentBlt() just isn't cutting it.

    I would like to be able to use an image and then a mask (or be able to render png's) but I have no idea of how to start this. Could anyone help me out?

    Thanks!

  2. #2
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    In GDI you can use the old two image approach. First blit it to the DC using SRCAND then blit using SRCPAINT

    This is a small snippet from my very old tile editor. You can look at StretchBlt in the Windows SDK for more detailed info about the parameters it needs. This is written for MFC but you can easily port it over to pure Win32.

    Code:
    ...
    ...
                      //Perform transparent stretch blit - blit the mask
                      m_pMemoryDC->StretchBlt( iX, iY, iTileW, iTileH, pTempDC,
                        0, 0, iOTileW,iOTileH,SRCAND);
                
                      pTempDC->SelectObject(pPrevMem);
                      pPrevMem=(CBitmap *)pTempDC->SelectObject(pImage);
                      
                      // Also note the use of SRCPAINT rather than SRCCOPY -  blit the image
                      m_pMemoryDC->StretchBlt(iX, iY, iTileW, iTileH, pTempDC,
                        0, 0,iOTileW,iOTileH,SRCPAINT);
    ...
    ...
    It's ugly but it works. Note that this code also used an offscreen DC so flickering was minimized.


    Moved to Windows Programming.
    Last edited by VirtualAce; 07-18-2009 at 01:19 PM.

  3. #3
    Registered User
    Join Date
    Apr 2009
    Posts
    45
    Awesome, thanks for replying! I'll go try this out.
    Sorry if it was in the wrong section.

  4. #4
    Registered User
    Join Date
    Apr 2009
    Posts
    45
    I'm having trouble with this for some reason....
    I'm not very good at windows programming, do you think you could convert your code to win32 and maybe expand it a little bit?

    When I tried converting it, the program ran fine, but my image looked... weird. I rendered the 'masked' image over a plain bitmap image and it seemed that the plain bitmap was messing with the mask if that's possible.... I have no idea. Any help on this would be appreciated.

  5. #5
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,249
    Quote Originally Posted by Flaug View Post
    I'm having trouble with this for some reason....
    I'm not very good at windows programming, do you think you could convert your code to win32 and maybe expand it a little bit?
    The calls to StretchBlt() and SelectObject() are identical to Win32, they are just being accessed through an MFC object. The code should map directly to Win32.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  6. #6
    Registered User
    Join Date
    Apr 2009
    Posts
    45
    I honestly don't know what I'm doing..... Here is my code:

    Code:
    void Player::Draw(HWND hWnd)
    {
    	HDC hDC = GetDC(hWnd);
    	HDC hMemDC = CreateCompatibleDC(hDC);
    
    	HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, imagemask);
    
    
    
    	StretchBlt(hDC, posx, posy, width, height, hMemDC, 0, 0, width, height, SRCAND);
    
    	SelectObject(hMemDC,hOldBitmap);
    	hOldBitmap = (HBITMAP)SelectObject(hMemDC, image);
    
    	StretchBlt(hDC, posx, posy, width, height, hMemDC, 0, 0, width, height, SRCPAINT);
    
    
    	SelectObject(hMemDC, hOldBitmap);
    	DeleteDC(hMemDC);
    	ReleaseDC(hWnd, hDC);
    }

  7. #7
    Unregistered User Yarin's Avatar
    Join Date
    Jul 2007
    Posts
    1,667
    Your code looks fine to me. But unless you actually are stretching the image in your application, use BitBlt instead.

    If you're having problems with the rendering just remember that your mask should be black for opaque areas, and white for transparent areas. While your color image should be black in the transparent areas.

    Also, you don't have to select the old bitmap back into the context until your done using it altogether.
    A class that doesn't overload all operators just isn't finished yet. -- SmugCeePlusPlusWeenie
    A year spent in artificial intelligence is enough to make one believe in God. -- Alan J. Perlis

  8. #8
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,249
    Quote Originally Posted by Yarin View Post
    Your code looks fine to me. But unless you actually are stretching the image in your application, use BitBlt instead.
    Coming from the driver side (GDI-DDI interface), I can tell you that what the driver sees is probably going to be a StretchBlt() anyway. The DDI interface will only use BitBlt() under a very limited set of circumstances, even if you are calling BitBlt() from the user side.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  9. #9
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    I used StretchBlt() at the time because I needed scaling flexibility. I also noticed that BitBlt() was not any faster than StretchBlt() which lends credence to what brewbuck stated.

  10. #10
    Registered User
    Join Date
    Apr 2009
    Posts
    45
    I can't believe I'm still having trouble with this.....
    I have a red line on a black background. When I render the image, the mask works correctly, except that the red line turns black. Why?
    Can anyone help me?

    {EDIT}
    Can the mask also use shades of gray to make the image semi-transparent? If not, why wouldn't I just use TransparentBlt()? (besides the fact that it has a known memory leak?)
    Last edited by Flaug; 07-22-2009 at 09:28 PM.

  11. #11
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    Read the Win32 help and you will find your answer.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem reading tiff image files?
    By compz in forum C++ Programming
    Replies: 9
    Last Post: 10-30-2009, 04:17 AM
  2. Replies: 1
    Last Post: 05-27-2009, 12:46 PM
  3. Simple Image Processing
    By ejohns85 in forum C++ Programming
    Replies: 4
    Last Post: 03-19-2009, 12:10 PM
  4. Replies: 4
    Last Post: 03-02-2003, 08:12 AM
  5. How to change a mouse cursor in console mode
    By GaPe in forum Windows Programming
    Replies: 10
    Last Post: 07-03-2002, 07:42 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21