0

In the OnPaint event of a TForm, I want to paint bitmaps that do not cover the background or other painted object because they have transparent parts.

If I draw an image over an image, it works.

But when I draw on the Form's Canvas, it does not work: the white part of the image, which is supposed to be transparent covers the other objects of the Canvas by a white square color.

Canvas->CopyMode = cmMergePaint ;
Graphics::TBitmap * Image=new Graphics::TBitmap();
Image->Transparent = true;
MainForm->Images->GetBitmap(14, Image);

Canvas->Draw(10,10,Image;
MainForm->Images->GetBitmap(0, Image);
Canvas->Draw(15,15,Image);

Update

When I draw on the Image using MainForm->Images->Draw(Image->Canvas...), I get a transparent square with nothing inside, that I can move over the other components.

When I draw using MainForm->Images->GetBitmap(ImgIndex[HisType]+Rotation, Image), I get the correct streched image on the Form, but without transparencies i.e. its white parts cover the other components.

While the MainForm->Images->Draw(Canvas, X, Y, ImgIndex[HisType]+Rotation, dsTransparent, itImage); does the job, I need to strech it for this component depending on a Size variable.

TRect DstRect(X,Y, X+32 + ( 1 - Rotation ) * 32 * Size, Y+32 + Rotation * 32 * Size);
Graphics::TBitmap * Image=new Graphics::TBitmap();
Image->Transparent=true;
//MainForm->Images->GetBitmap(ImgIndex[HisType]+Rotation, Image);
MainForm->Images->Draw(Image->Canvas, 0, 0, ImgIndex[HisType]+Rotation, dsTransparent, itImage);
Canvas->StretchDraw(DstRect, Image);
delete Image;

//MainForm->Images->Draw(Canvas, X, Y, ImgIndex[HisType]+Rotation, dsTransparent, itImage);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Lotfi
  • 660
  • 1
  • 6
  • 21
  • @Remy Lebeau Do you have a solution to get both (stretch + transparency), the above code can give one of them only. – Lotfi Feb 09 '19 at 00:04
  • 1
    @Lofti As I already stated in earlier comments (which appear to have since been deleted), the problem when using `Images->Draw(Images->Canvas, ...)` is that you are not setting `Image->Width` and `Image->Height` before then drawing on `Image`. `Images->GetBitmap()` handles that for you, but `Images->Draw()` does not, so you need to add that to your code. – Remy Lebeau Feb 09 '19 at 02:23
  • @Remy still having no transparency of the bitmap. How can I do this `TRect R1; Size=1; //debug TRect DstRect(X,Y, X+32 + ( 1 - Rotation ) * 32 * Size, Y+32 + Rotation * 32 * Size); Graphics::TBitmap * Image=new Graphics::TBitmap(); Image->Transparent=true; Image->Width = 32; Image->Height = 32; //MainForm->Images->GetBitmap(ImgIndex[HisType]+Rotation, Image); MainForm->Images->Draw(Image->Canvas, 0, 0, ImgIndex[HisType]+Rotation); //Canvas->Draw(X,Y,Image); Canvas->StretchDraw(DstRect, Image); delete Image;` – Lotfi Feb 09 '19 at 11:32
  • in fact, my image is not transparent and Image->Transparent=true; does not make it transparent. Something is missing – Lotfi Feb 09 '19 at 12:17
  • try drawing the bitmap first, then set it `Transparent=true` afterwards, and maybe also set its `TransparentColor` if needed. – Remy Lebeau Feb 09 '19 at 18:00
  • @Remy No that doesn't help, but I found that we must first fill the newly created bitmap with one color and not let it empty in order to transparency to work: `Image->Canvas->FillRect(Rect(0,0,32,32));` – Lotfi Feb 09 '19 at 19:23

2 Answers2

1

Use Images->Draw() instead, let the TImageList handle the drawing for you:

MainForm->Images->Draw(Canvas, 10, 10, 14, dsTransparent, itImage);
MainForm->Images->Draw(Canvas, 15, 15, 0, dsTransparent, itImage);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Yes Remy, this works, but I gave only a simple example to ask my question. In fact, I need to draw some components (when I am moving them with the mouse) on the Form->Canvas. Is there a possibility to draw from the Image and not from the TImageList? (Draw does not exists for Image) – Lotfi Feb 06 '19 at 22:18
  • @Lotfi why are you drawing components manually at all? You should be letting them draw themselves normally. What are you trying to accomplish exactly? – Remy Lebeau Feb 07 '19 at 01:04
  • I am translating my old program I made on Pascal Object 7.0 to C++ builder http://www.baghli.com/powerd.html so the collection of components needs to be drawn. Your method is ok for the normal Images, but one of them need to be stretched before being paint on the Form. So I need the possibility to draw from a bitmap or Timage with the possibility of transparency. – Lotfi Feb 07 '19 at 12:43
  • 1
    @Lotfi create a transparent `TBitmap`, `TImageList.Draw()` onto the bitmap, and then `Canvas.StretchDraw()` the bitmap. – Remy Lebeau Feb 07 '19 at 16:21
0

Found the solution, Thank to Remy. We must first fill the newly created bitmap with one color and not let it empty in order to transparency to work...

Size=1; //debug
TRect DstRect(X,Y, X+32 + ( 1 - Rotation ) * 32 * Size, Y+32 + Rotation * 32 * Size);
Graphics::TBitmap * Image=new Graphics::TBitmap();
Image->Width = 32;
Image->Height = 32;
Image->Canvas->FillRect(Rect(0,0,32,32));
MainForm->Images->GetBitmap(ImgIndex[HisType]+Rotation, Image);
//MainForm->Images->Draw(Image->Canvas, 0, 0, ImgIndex[HisType]+Rotation, dsTransparent, itImage);
Image->Canvas->Pen->Color = clRed;
Image->Canvas->MoveTo( 3, 3 );
Image->Canvas->LineTo( 29, 29 );
Image->Transparent=true;
Canvas->StretchDraw(DstRect, Image);
delete Image;
Lotfi
  • 660
  • 1
  • 6
  • 21
  • You should define a specific color for [`FillRect()`](http://docwiki.embarcadero.com/Libraries/en/Vcl.Graphics.TCanvas.FillRect) (it defaults to White): `Image->Canvas->Brush->Color = ...;` (`clFuschia` is commonly used). If you don't set a [`TransparentColor`](http://docwiki.embarcadero.com/Libraries/en/Vcl.Graphics.TBitmap.TransparentColor), the bitmap will use the color in the first left-most pixel. If `Draw()` *happens* to draw in that pixel, your bitmap may not render the way you expect. So you should explicitly set the `TransparentColor` to the same color you tell `FillRect()` to use. – Remy Lebeau Feb 09 '19 at 20:21
  • yes I understand that but it is ok since all the drawing is far from the edges – Lotfi Feb 12 '19 at 17:01
  • it's not just about the edges, it's about the colors, too. Like I said, the default brush color is white, so if your drawing includes white pixels, they will end up transparent, which may or may not be what your want, depending on your particular images. Just saying... – Remy Lebeau Feb 12 '19 at 17:13