Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17


Image transparency in Delphi under Windows XP

Posted on 2004-10-12
Medium Priority
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 500 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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA:…
Suggested Courses

705 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