Lazarus

Programming => Graphics and Multimedia => Graphics => Topic started by: krzynio on May 21, 2019, 12:47:39 pm

Title: Writting text on transparent image from ImageList
Post by: krzynio 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
Title: Re: Writting text on transparent image from ImageList
Post by: Mr.Madguy 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.
Title: Re: Writting text on transparent image from ImageList
Post by: krzynio 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.
       
Title: Re: Writting text on transparent image from ImageList
Post by: furious programming 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 (https://forum.lazarus.freepascal.org/index.php/topic,44486.0.html). 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 (http://wiki.freepascal.org/fcl-image#Image_formats).
Title: Re: Writting text on transparent image from ImageList
Post by: lainz on May 25, 2019, 03:31:17 am
Use bgrabitmap, it works fine and is easy to use.
Title: Re: Writting text on transparent image from ImageList
Post by: krzynio 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.
Title: Re: Writting text on transparent image from ImageList
Post by: circular 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.
Title: Re: Writting text on transparent image from ImageList
Post by: krzynio 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.