Image transparency in Delphi under Windows XP

Posted on 2004-10-12
Last Modified: 2010-04-16

I use TImage for writing text on its canvas with TextOut method. My images are all defined transparent, and when I work under Windows 2000, they do look transparent. However, when I run my application under Windows XP, only some parts of an image become transparent, namely those with text lines on them. All the remaining area of the image is white.

You can see the screenshots here:   (Windows 2000)   (Windows XP)

How can I solve this problem?

Vadim Smolensky,
St.Petersburg, Russia
Question by:VSmolensky
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3

Expert Comment

ID: 12294287
Have you tried using a more contrasting colour for the transparency? In transparent images the more contrast in the image the better the transparency. With black text try a white background. Or a nother method is to use a colour which is similar too, but not the same as the text e.g. dark brown.

As for the difference between 2000 and XP i am unsure, all i can reccomend is adjusting you image contrasts.

Best regards,


Author Comment

ID: 12295185
Thank you for the suggestion, but your advice looks strange. Transparency isn't Alpha property, it can't be better or worse depending on contrasts. Tranparency either exists or not, it's a binary thing. And in my case, it obviously doesn't work properly at all.


Expert Comment

ID: 12295750
I have found from experience with transparent forms that if you have a bitmap with a colour that is close to what you want remaining then you will get a better result. Similarly this will also work if the colour is strongly opposite (perhaps contrast was the wrong word). In your case i think you are right it is not a problem that could be solved using my method - you can but try though :-)


Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Expert Comment

ID: 12314989
Have you tried bitblt instead? This code may be of use to you:

procedure tform1.DrawTransparentBitmap(DC: HDC; hBmp : HBITMAP ;
          xStart: integer; yStart : integer; cTransparentColor : COLORREF);
      bm:                                                  BITMAP;
      cColor:                                              COLORREF;
      bmAndBack, bmAndObject, bmAndMem, bmSave:            HBITMAP;
      bmBackOld, bmObjectOld, bmMemOld, bmSaveOld:         HBITMAP;
      hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave:        HDC;
      ptSize:                                              TPOINT;

   hdcTemp := CreateCompatibleDC(dc);
   SelectObject(hdcTemp, hBmp);   // Select the bitmap

   GetObject(hBmp, sizeof(BITMAP), @bm);
   ptSize.x := bm.bmWidth;            // Get width of bitmap
   ptSize.y := bm.bmHeight;           // Get height of bitmap
   DPtoLP(hdcTemp, ptSize, 1);        // Convert from device
                                      // to logical points

   // Create some DCs to hold temporary data.
   hdcBack   := CreateCompatibleDC(dc);
   hdcObject := CreateCompatibleDC(dc);
   hdcMem    := CreateCompatibleDC(dc);
   hdcSave   := CreateCompatibleDC(dc);

   // Create a bitmap for each DC. DCs are required for a number of
   // GDI functions.

   // Monochrome DC
   bmAndBack   := CreateBitmap(ptSize.x, ptSize.y, 1, 1, nil);

   // Monochrome DC
   bmAndObject := CreateBitmap(ptSize.x, ptSize.y, 1, 1, nil);

   bmAndMem    := CreateCompatibleBitmap(dc, ptSize.x, ptSize.y);
   bmSave      := CreateCompatibleBitmap(dc, ptSize.x, ptSize.y);

   // Each DC must select a bitmap object to store pixel data.
   bmBackOld   := SelectObject(hdcBack, bmAndBack);
   bmObjectOld := SelectObject(hdcObject, bmAndObject);
   bmMemOld    := SelectObject(hdcMem, bmAndMem);
   bmSaveOld   := SelectObject(hdcSave, bmSave);

   // Set proper mapping mode.
   SetMapMode(hdcTemp, GetMapMode(dc));

   // Save the bitmap sent here, because it will be overwritten.
   BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);

   // Set the background color of the source DC to the color.
   // contained in the parts of the bitmap that should be transparent
   cColor := SetBkColor(hdcTemp, cTransparentColor);

   // Create the object mask for the bitmap by performing a BitBlt
   // from the source bitmap to a monochrome bitmap.
   BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0,

   // Set the background color of the source DC back to the original
   // color.
   SetBkColor(hdcTemp, cColor);

   // Create the inverse of the object mask.
   BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0,

   // Copy the background of the main DC to the destination.
   BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, dc, xStart, yStart,

   // Mask out the places where the bitmap will be placed.
   BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);

   // Mask out the transparent colored pixels on the bitmap.
   BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);

   // XOR the bitmap with the background on the destination DC.
   BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);

   // Copy the destination to the screen.
   BitBlt(dc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0,

   // Place the original bitmap back into the bitmap sent here.
        BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);

   // Delete the memory bitmaps.
   DeleteObject(SelectObject(hdcBack, bmBackOld));
   DeleteObject(SelectObject(hdcObject, bmObjectOld));
   DeleteObject(SelectObject(hdcMem, bmMemOld));
   DeleteObject(SelectObject(hdcSave, bmSaveOld));

   // Delete the memory DCs.

procedure TForm1.Button1Click(Sender: TObject);
DrawTransparentBitmap(Form1.Canvas.Handle, Image1.Picture.Bitmap.Handle, 10, 10, clWhite);

Author Comment

ID: 12347687
It's quite probable that this piece of code will work properly. But I wouldn't like to make my code too sophisticated. Under Windows 2K, it was enough to assign Trasparent:=True. I'm sure the solution for Windows XP must also be very simple. We just have to understand the difference between the two platforms.


Expert Comment

ID: 12352447
You should still be able to assign Trasparent:=True in XP, i know i can. I'm using XP myself and i have not had problems such as yours since i have found the transparency to work fine if i adjust the transparent colour so i don't get the halo effect. Have you tested you app of another XP system? Also see what happens using a different image - do you get the same problem?



Accepted Solution

phervers earned 125 total points
ID: 12392510

first try setting TransparentMode := tmFixed;
TransparentColor := yourTransparentColor;

also before calling TextOut

set Canvas.Brush.Color := yourTransparentColor;

it should help

another solution would be simply filling bitmap with bg color using FillRect

Author Comment

ID: 12411739

FillRect works perfectly well. Also, FloodFill gives the same effect. Looks like every pixel of the bitmap must be processed somehow to make the image truly transparent.

Thank you very much!

Featured Post

Ready to get started with anonymous questions?

It's easy! Check out this step-by-step guide for asking an anonymous question on Experts Exchange.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses
Course of the Month8 days, 3 hours left to enroll

617 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question