Recent

Author Topic: Writting text on transparent image from ImageList  (Read 808 times)

krzynio

  • Jr. Member
  • **
  • Posts: 73
Writting text on transparent image from ImageList
« on: May 21, 2019, 12:47:39 pm »
What I wanted to do is to copy an image from image list to bitmap b2, next write text on this b2 bitmap, then paste it to bitmap of the image.
Image must be transparent.
When I copy bitmap from TImageList to bitmap b2 and copy it to bitmap b the result is correct.
But when I copy image from the ImageList to bitmap b2 then write some text on it and next copy b2 to b1 then in place of written text a transparent rectangle is displayed. I save the image of b2 into the file and I see that text on b2 is correct. The bug seems to be in Draw function which copies the image from b2 into b or maybe I something in wrong way.

Code: Pascal  [Select]
  1.         Image.Transparent := True;
  2.         b := Image.Picture.Bitmap;
  3.         b.PixelFormat := pf32bit;
  4.         b.Transparent := True;
  5.         b.TransparentColor := clFuchsia;
  6.         b.TransparentMode := tmFixed;
  7.         b.Canvas.CopyMode := cmSrcCopy;
  8.         b.Canvas.Brush.Style := bsSolid;
  9.         b.Canvas.Brush.Color := b.TransparentColor;
  10.         b.Canvas.FillRect(0,0,w,h);
  11.  
  12.         b2 := TBitmap.Create;
  13.         b2.PixelFormat := pf32bit;
  14.         dm.il64x50.GetBitmap(1, b2);
  15.  
  16.         b2.Canvas.Font.Size := 8;
  17.         b2.Canvas.Brush.Color := clFuchsia;
  18.         b2.Canvas.Brush.Style := bsSolid;
  19.         b2.Canvas.Font.Style := [];
  20.         b2.Canvas.Font.Color := clBlack;
  21.         b2.Canvas.TextOut(10,40, 'XXXXXXX');
  22.         b2.SaveToFile('d:\xx.bmp'); // here transparent text is visible
  23.  
  24.         b.Canvas.Draw(0,(w-64) div 2, b2); // here the text is not visible, just empty rectangle is visible in place of the text
  25.         b2.Free;
  26.  

Lazarus 2.1 (svn) on Windows 10 1809 64-bit
« Last Edit: May 21, 2019, 12:49:29 pm by krzynio »
Lazarus version: trunk. FPC version: 3.0.4. OS: Linux Debian Testing x64 with XFCE 4.12 and Windows 10 x64 version: 1709

Mr.Madguy

  • Sr. Member
  • ****
  • Posts: 455
Re: Writting text on transparent image from ImageList
« Reply #1 on: May 23, 2019, 12:00:56 pm »
Have you tried this?
Code: Pascal  [Select]
  1. b2.Canvas.Font.Color := clBlack or $ff000000;
  2.  
But anyway. As I remember pure Canvas doesn't fully support transparency. I was asked in some thread, if it was possible to modify semi-transparent icon. And, as I remember, exporting it to DIB, modifying it and then importing it back - was the only working solution.

Another reason: Canvas doesn't support semi-transparency at all. It uses 1bpp mask bitmap in order to emulate transparency. And this bitmap is generated, only when Transparent or TransparentColor are modified. So, if you modify bitmap after this, transparency can stay unmodified. But I'm not sure about it. I'll need to look into code in order to confirm it.
« Last Edit: May 23, 2019, 12:08:29 pm by Mr.Madguy »
DynamicData 3.0 is released!
Since now development is frozen - only optimization passes will be made at some point.
Lack of multiple inheritance turns it into abomination.

krzynio

  • Jr. Member
  • **
  • Posts: 73
Re: Writting text on transparent image from ImageList
« Reply #2 on: May 23, 2019, 12:11:21 pm »
Thank you. I tried a minute ago. Doesn't work.
I can write when I replace
Code: Pascal  [Select]
  1. dm.il64x50.GetBitmap(0, b3);
with
Code: Pascal  [Select]
  1. b3.LoadFromFile('comp.bmp');
but after this action I'm loosing transparency.
       
Lazarus version: trunk. FPC version: 3.0.4. OS: Linux Debian Testing x64 with XFCE 4.12 and Windows 10 x64 version: 1709

furious programming

  • Sr. Member
  • ****
  • Posts: 354
  • I click a little.
Re: Writting text on transparent image from ImageList
« Reply #3 on: May 23, 2019, 04:24:43 pm »
@krzynio: the PixelFormat property does not allow you to manipulate the depth of the bitmap.

Try with the TFPMemoryImage, TFPImageCanvas and TFPWriterBMP classes. An example of using these classes can be found in my thread. Admittedly, it concerns painting a bitmap and exporting it to a 4-bit form, but it's always a beginning. More informations you can find in this article.
Lazarus 2.0.4 with FPC 3.0.4, Windows XP (all 32-bit)

lainz

  • Hero Member
  • *****
  • Posts: 3228
    • Lainz
Re: Writting text on transparent image from ImageList
« Reply #4 on: May 25, 2019, 03:31:17 am »
Use bgrabitmap, it works fine and is easy to use.

krzynio

  • Jr. Member
  • **
  • Posts: 73
Re: Writting text on transparent image from ImageList
« Reply #5 on: May 28, 2019, 01:25:44 pm »
Thank you!

BGRABitmap works really fine. The only inconvenience is that the text is written with anti-alias and it has a little outline in color similar to transparent color thus. Can I turn off witting with anti-alias on BGRABitmap?
Adding
Code: Pascal  [Select]
  1. b2.CanvasBGRA.AntialiasingMode := amOff;
  2. b2.CanvasBGRA.Font.Antialiasing := False;  
seems to be not working. Text remains smooth.
« Last Edit: May 28, 2019, 01:39:48 pm by krzynio »
Lazarus version: trunk. FPC version: 3.0.4. OS: Linux Debian Testing x64 with XFCE 4.12 and Windows 10 x64 version: 1709

circular

  • Hero Member
  • *****
  • Posts: 2982
    • Personal webpage
Re: Writting text on transparent image from ImageList
« Reply #6 on: May 29, 2019, 12:36:02 am »
Antialiasing property ensures fine antialiasing, but the system font renderer often does some antialiasing anyway.

One could try and remove antialiasing, though that would not be very beautiful. Also you can have an actual transparent background with BGRABitmap.

If your original image has fuchsia to represent the transparent color, you can do
Code: [Select]
    Bitmap.Replace(CSSFuchsia, BGRAPixelTransparent);and then draw the text with antialiasing on top of it.
Conscience is the debugger of the mind

krzynio

  • Jr. Member
  • **
  • Posts: 73
Re: Writting text on transparent image from ImageList
« Reply #7 on: May 29, 2019, 07:40:50 am »
Thank you works like a charm!
Here is my code for the others.
Code: Pascal  [Select]
  1. tOb[i].im.Transparent := True;
  2. b := tOb[i].im.Picture.Bitmap;
  3. b.PixelFormat := pf32bit;
  4. b.TransparentColor := clFuchsia;
  5. b.Transparent := True;
  6. b.TransparentMode := tmFixed;
  7. b.Canvas.CopyMode := cmSrcCopy;
  8. b.Canvas.Brush.Style := bsSolid;
  9. b.Canvas.Brush.Color := b.TransparentColor;
  10. b.Canvas.FillRect(0,0,w,h);
  11. //dm.il64x50.GetBitmap(1, b2);
  12. b2 := TBGRABitmap.Create('comp80x64.bmp');
  13. b2.ReplaceColor(CSSFuchsia, BGRAPixelTransparent); // turn off anti-aliasing for fonts
  14. b2.CanvasBGRA.Font.Height := -10;
  15. fh := b2.Height-(b2.CanvasBGRA.TextHeight('Fj')-2);
  16. b2.CanvasBGRA.Font.Style := [fsBold];
  17. b2.CanvasBGRA.Font.Color := clBlack;
  18. b2.CanvasBGRA.Brush.Style := bsClear;
  19. b2.CanvasBGRA.TextOut(CenterX(0, w, tOb[i].NAZMASZ, b2.Canvas), fh, tOb[i].NAZMASZ);
  20. b.Canvas.Draw(0,0,b2.Bitmap);
  21. b2.Free;
  22.  
« Last Edit: May 29, 2019, 07:42:36 am by krzynio »
Lazarus version: trunk. FPC version: 3.0.4. OS: Linux Debian Testing x64 with XFCE 4.12 and Windows 10 x64 version: 1709