Recent

Author Topic: [solved][qt5] TImageList.CreateMasked fails when transparent color is clGrayText  (Read 1535 times)

Valdas

  • New Member
  • *
  • Posts: 49
Hello,

main form class has a image list as variable (sample project is attached):
Code: Pascal  [Select][+][-]
  1. FImageList: TImageList;
During the form creation event a bitmap was created with the intent of transparency and then it was added into the image list using AddMasked method:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. const
  3.   BITMAP_SIZE = 51;
  4.   COLOR_BACKGROUND = clGreen;
  5.   //COLOR_TRANSPARENT = clBtnFace; // <-- works
  6.   COLOR_TRANSPARENT = clGrayText;  // <--- fails
  7.   COLOR_OBJECT = clRed;
  8. var
  9.   bitmap: TBitmap;
  10. begin
  11.     Caption := LCLPlatformDisplayNames[WidgetSet.LCLPlatform];
  12.     Color := COLOR_BACKGROUND;
  13.  
  14.     FImageList := TImageList.Create(self);
  15.     FImageList.Width := BITMAP_SIZE;
  16.     FImageList.Height := BITMAP_SIZE;
  17.  
  18.     bitmap := TBitmap.Create;
  19.     bitmap.Width := BITMAP_SIZE;
  20.     bitmap.Height := BITMAP_SIZE;
  21.     bitmap.TransparentMode := tmFixed;
  22.     bitmap.TransparentColor := COLOR_TRANSPARENT;
  23.     //
  24.     bitmap.Canvas.Brush.Color := COLOR_TRANSPARENT;
  25.     bitmap.Canvas.FillRect(0, 0, BITMAP_SIZE, BITMAP_SIZE);
  26.     //
  27.     bitmap.Canvas.Brush.Color := COLOR_OBJECT;
  28.     bitmap.Canvas.Pen.Color := COLOR_OBJECT;
  29.     bitmap.Canvas.Ellipse(0, 0, BITMAP_SIZE, BITMAP_SIZE);
  30.  
  31.     FImageList.AddMasked(bitmap, COLOR_TRANSPARENT);
  32.     bitmap.Free;
  33. end;
  34.  
In the form's OnPaint event the image is drawn from the image list:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormPaint(Sender: TObject);
  2. begin
  3.     FImageList.Draw(Canvas, 0, 0, 0);
  4. end;
  5.  
If I use a color other than clGrayText for transparent parts of the image then I get transparency when I draw on the canvas (first image).
But clGrayText as transparency color removes transparency (second image).

When using the GTK2 widgetset I don't see this strange effect.

Is this a bug?
« Last Edit: March 17, 2023, 07:01:12 am by Valdas »

zeljko

  • Hero Member
  • *****
  • Posts: 1596
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Maybe, should be tested with pure Qt to see if that's true.

wp

  • Hero Member
  • *****
  • Posts: 11923
I would not work with that ancient color transparency - I always had lots of issues with it. It's better to go to pf32Bit Pixelformat and introduce a true alpha channel. However, the painting routines in the Graphics unit cannot handle this usually, and therefore it is recommended to switch to a TLazIntfImage and the TLazCanvas. Have a look at the wiki, there are several code samples: https://wiki.freepascal.org/Developing_with_Graphics#Working_with_TLazIntfImage.2C_TRawImage_and_TLazCanvas

Code: Pascal  [Select][+][-]
  1. uses
  2.   FpImage, IntfGraphics, LazCanvas;
  3.  
  4. procedure TForm1.FormCreate(Sender: TObject);
  5. const
  6.   BITMAP_SIZE = 51;
  7.   COLOR_BACKGROUND = clGreen;
  8.   COLOR_OBJECT = clRed;
  9. var
  10.   bitmap: TBitmap;
  11.   img: TLazIntfImage;
  12.   cnv: TLazCanvas;
  13. begin
  14. //  Caption := LCLPlatformDisplayNames[WidgetSet.LCLPlatform];
  15.   Color := COLOR_BACKGROUND;
  16.  
  17.   FImageList := TImageList.Create(self);
  18.   FImageList.Width := BITMAP_SIZE;
  19.   FImageList.Height := BITMAP_SIZE;
  20.  
  21.   bitmap := TBitmap.Create;
  22.   bitmap.PixelFormat := pf32bit;
  23.   bitmap.SetSize(BITMAP_SIZE, BITMAP_SIZE);
  24.   img := bitmap.CreateIntfImage;
  25.   cnv := TLazCanvas.Create(img);
  26.   // Fill the image with transparent "color"
  27.   cnv.Brush.FPColor := colTransparent;
  28.   cnv.FillRect(0, 0, img.Width, Img.Height);
  29.   // Draw the ellipse in opaque color
  30.   cnv.Brush.FPColor := TColorToFPColor(COLOR_OBJECT);  // or declare COLOR_OBJECT as colRed which is the 64-bit color red in FCL-image)
  31.   cnv.Pen.FPColor := TColorToFPColor(COLOR_OBJECT);
  32.   cnv.Ellipse(0, 0, BITMAP_SIZE, BITMAP_SIZE);
  33.   bitmap.LoadFromIntfImage(img);
  34.   FImageList.Add(bitmap, nil);
  35.   cnv.Free;
  36.   img.Free;
  37.   bitmap.Free;
  38. end;
  39.  
  40. procedure TForm1.FormPaint(Sender: TObject);
  41. begin
  42.   FImageList.Draw(Canvas, 0, 0, 0);
  43. end;

Valdas

  • New Member
  • *
  • Posts: 49
Yes, a much better approach. Thank you!

 

TinyPortal © 2005-2018