Recent

Author Topic: SOLVED: How to use SVG images  (Read 14396 times)

fatmonk

  • Sr. Member
  • ****
  • Posts: 252
SOLVED: How to use SVG images
« on: May 17, 2017, 06:32:16 pm »
Reading around it seems that BGRABitmap now supports SVG... but I can't find any info on how to use SVG images and exactly what is supported.

I have a couple of SVG icons I want to display and scale along with a UI.

Can anyone point me in the right direction?

Thanks,

FM
« Last Edit: May 19, 2017, 01:46:24 pm by fatmonk »

Handoko

  • Hero Member
  • *****
  • Posts: 5122
  • My goal: build my own game engine using Lazarus
Re: How to use SVG images
« Reply #1 on: May 17, 2017, 06:39:52 pm »
I do not use BGRABitmap, but I think you may download and try the TEST SVG from this thread:

https://forum.lazarus.freepascal.org/index.php?topic=36692.0

fatmonk

  • Sr. Member
  • ****
  • Posts: 252
Re: How to use SVG images
« Reply #2 on: May 18, 2017, 04:47:57 pm »
I downloaded that (I'd read that thread but missed the attachment at the top!) and have had a play with the test project.

After a bit of playing around I've got a version of that test project (attached) that allows me to scale an SVG on the fly (kind of brute forcing it a bit, so there may be a slicker, more efficient way of doing it).

However, the test project only reads from a file. I'd like to include the SVG(s) with the executable. I'll play some more, but ideally I'd be able to include the XML of the SVG directly in my project and create the in-UI image from that - that would even allow me to manipulate things like the colours in the graphic on the fly...

-FM

fatmonk

  • Sr. Member
  • ****
  • Posts: 252
Re: How to use SVG images
« Reply #3 on: May 18, 2017, 05:06:47 pm »
OK, a bit more progress...

Using the StringToStream() function from this StackExchange answer I have managed to include the SVGs as string variables directly in the code.

New version attached.

I am, however, getting a load of messages from Heap Trace (heaptrc) when exiting this test project, so I am reluctant to add this code to my live project... What am I doing wrong to get these heap errors?

-FM

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: How to use SVG images
« Reply #4 on: May 18, 2017, 06:26:04 pm »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

fatmonk

  • Sr. Member
  • ****
  • Posts: 252
Re: How to use SVG images
« Reply #5 on: May 18, 2017, 06:38:59 pm »
I should have pointed out that I want this to be cross platform!

I think embedding the SVG XML as a text string is the way I'm going to achieve this as it allows me to manipulate the image colours etc as well.

-FM

fatmonk

  • Sr. Member
  • ****
  • Posts: 252
Re: How to use SVG images
« Reply #6 on: May 19, 2017, 01:46:06 pm »
Here's a much simpler example.

- It uses an embedded SVG string as the scalable graphic to everything is self contained.
- It uses BGRABitmap and BGRASVG only.
- It doesn't appear to suffer from any memory leaks (feel free to test and let me know if it does as this is an area I want to learn more about).
- It should be cross platform as it does not rely on any windows specific resource embedding.

To test, simply run and try rescaling the form and the SVG scales smoothly...

-FM

(Demo Built and tested with BGRABitmap 9.5)

Handoko

  • Hero Member
  • *****
  • Posts: 5122
  • My goal: build my own game engine using Lazarus
Re: SOLVED: How to use SVG images
« Reply #7 on: June 19, 2017, 07:56:47 am »
I just downloaded and tested your "My SVG Test.zip". I'm sorry to say it is not working correctly. Please see the image. The top one is the original, which I noticed something weird (the blue lines). The lowers are the resized versions.

Tested on Lazarus 1.6.4 FPC 3.0.2 Linux64 Gtk2 + BGRABitmap 9.5.0.0.

circular

  • Hero Member
  • *****
  • Posts: 4181
    • Personal webpage
Re: SOLVED: How to use SVG images
« Reply #8 on: June 19, 2017, 08:53:43 pm »
@Handoko: it works fine here. Maybe transparency is different on Linux. How about adding bmp.Fill(clSilver) before svg.StretchDraw?

Note : StringToStream function allocates a stream that needs to be freed to avoid memory leak.

Since using a string seems a good idea, I've added TBGRAUTF8.CreateFromString and also AsUTF8String property (on dev-bgrabitmap branch).

Code: Pascal  [Select][+][-]
  1. svg:= TBGRASVG.CreateFromString(SVGcontent);
Conscience is the debugger of the mind

Handoko

  • Hero Member
  • *****
  • Posts: 5122
  • My goal: build my own game engine using Lazarus
Re: SOLVED: How to use SVG images
« Reply #9 on: June 21, 2017, 07:38:09 am »
Problem solved.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2.   Var
  3.    bmp: TBGRABitmap;
  4.    svg: TBGRASVG;
  5. begin
  6.    bmp:= TBGRABitmap.Create;
  7.    try
  8.     svg:= TBGRASVG.Create(StringToStream(SVGcontent));
  9.     try
  10.      if (Image1.Width > 0) and (Image1.Height > 0)
  11.      then
  12.        begin
  13.          bmp.SetSize(Round(Image1.Width),Round(Image1.Height));
  14.          bmp.Fill(clSilver);
  15.          svg.StretchDraw(bmp.Canvas2D, taCenter, tlCenter, 0,0,Image1.Width,Image1.Height);
  16.          Image1.Picture.Bitmap.Assign(bmp);
  17.        end;
  18.     finally
  19.      svg.Free;
  20.     end;
  21.    finally
  22.     bmp.Free;
  23.    end;
  24. end;
« Last Edit: June 21, 2017, 07:40:57 am by Handoko »

fatmonk

  • Sr. Member
  • ****
  • Posts: 252
Re: SOLVED: How to use SVG images
« Reply #10 on: June 16, 2021, 01:53:16 pm »
@Handoko: it works fine here. Maybe transparency is different on Linux. How about adding bmp.Fill(clSilver) before svg.StretchDraw?

Note : StringToStream function allocates a stream that needs to be freed to avoid memory leak.

Since using a string seems a good idea, I've added TBGRAUTF8.CreateFromString and also AsUTF8String property (on dev-bgrabitmap branch).

Code: Pascal  [Select][+][-]
  1. svg:= TBGRASVG.CreateFromString(SVGcontent);

Did this ever make it into a release branch of BGRABitmap?

I have the 2021.01.03 version, but can't find the CreatFromString method...

Thanks,

FM

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: SOLVED: How to use SVG images
« Reply #11 on: June 16, 2021, 02:15:19 pm »
Hi1

It is not a method, it is a constructor and exists since a lot of versions:

Code: Pascal  [Select][+][-]
  1.  TBGRASVG = class(TSVGCustomElement)  
  2.  ...
  3.  ...
  4.  constructor CreateFromString(AUTF8String: string);
 

Winni

 

TinyPortal © 2005-2018