Jump to content

angusj

Members
  • Content Count

    132
  • Joined

  • Last visited

  • Days Won

    8

Posts posted by angusj


  1. OK, all fixed now. I've attached a working example.

    The  example loads a QOI file and saves it to BMP, then loads the saved BMP and saves that to a second QOI, and finally loads the second QOI and saves as a second BMP.

     

    Edit: Another minor bugfix (with thanks to feedback from kadaif).

    Edit2: Deleted obsolete attachment. See post below.

     

    • Like 3
    • Thanks 1

  2. 23 hours ago, dummzeuch said:

    Is anybody maybe already working on a 32 bit Pascal/Delphi implementation?

    The following seems OK reading QOI files/streams ...

     

     

    Edit: Just spotted an occassional artefact in the rendered images that I'm now chasing.

    I've also written the WriteToStream code (that seems bug free) that I'll upload once I've found and fixed the bug in the ReadFromStream code above.

     

    Edit2: Code sample above deleted. See bugfixed version in zip package below.

    • Thanks 2

  3. 1 minute ago, Anders Melander said:

    Why should they? I mean, what's the benefit?

    Persisting with my dance analogy, being so late to the dance everyone has partnered up.

    IOW, browers must support formats that webpages use, and webpages will use what browsers support.

    But as I said above, there's little cost to browsers supporting QOI given the simplicity of the compression and decompression algorithms.

    Time will tell.


  4. 10 minutes ago, TimCruise said:

    I am using the Delphi Community v10.4.2.

    I can run the bouncing green ball project, however.

    I am totally new to this software and catching up quite well.  I guess it can help me to build a very large dashboard GUI. :classic_cheerleader:

    Hi again Tim. I see in another thread that you've installed Image32 as part of SVGIconImageList. I suspect the problem lies there and you may need to temporarily uninstall 
    SVGIconImageList and reinstalling Image32 before compiling the FMX sample apps. Otherwise, I'm not aware of anyone else having problems with compiling the samples.

    • Confused 1

  5. 42 minutes ago, Edwin Yip said:

    The Image32-based controls demo is cool! And this seems to be a new feature added most recently.

    It's a soon to be released **experimental** (or proof of concept) unit that creates visual controls entirely independant of VCL and FMX.

    However, these controls would really require a lot of work to make genuinely useful and ISTM that I'm probably just reinventing the wheel.

    Having said that this new Img32.CTRL unit could be very useful if there were reasonably simple Linux, Android and Mac equivalents of the Window's CreateWindow/WindowProc GUI.

     


  6. 1 hour ago, wuwuxin said:

    is it suitable to be used for developing CAD-like application, or interactive 2D graphics (that is based on user mouse dragging etc)?

    Hi wuwuxin. Here are several short videos that demonstrate Image32's interactive capabilities...

    http://www.angusj.com/delphi/image32/Videos/img32.ctrls.mkv

    http://www.angusj.com/delphi/image32/Videos/layers301.mkv

    http://www.angusj.com/delphi/image32/Videos/layers201.mkv

     

     

    • Like 3
    • Thanks 1

  7. 1 hour ago, Anders Melander said:

    If you're focusing on performance

    I got the impression from the OP that he was primarily interested in relative performance (ie Skia vs VCL) rather than perfectly optimised performance.

    I think we've demonstrated that third-party libraries offer no performance benefit when we're only considering coloring individual pixels.


  8. 3 hours ago, hsauro said:

    The advantage of skia over these other two is that it’s completely cross-platform

    Hi hsauro. Image32 should be completely cross-platform, so I'd be very interested if you've encountered problems in that regard.

     

    6 hours ago, M.Joos said:

    My guess: Graphics32 would even outperform this.

    I also doubt this since the drawing is done by directly addressing (ie coloring) every individual pixel (not by using a polygon renderer). There'd be little to no benefit in using another graphics library here. You could perhaps marginally improve pixel addressing by converting the temporary bitmap into a pf32bit pixelformat, getting the base image address (from bitmap.Scanline[bitmap.Height -1]) and efficiently offsetting that pointer to color everything (as per below).

     

    procedure DrawMandelbrotVCL2(bmp: TBitmap; X, Y, au, bu: Double; X2, Y2: Integer);
    var
      c1, c2, z1, z2, tmp: Double;
      i, j, Count, rgb: Integer;
      hue, saturation, value : double;
      fr, fg, fb : single;
      ACanvas: TCanvas;
      p, currPixel: PColor;
      bytesPerLine: integer;
    begin
      bmp.PixelFormat := pf32bit;
      //nb: should probably test here for the occas. non-inverted image
      p := bmp.ScanLine[0];
      bytesPerLine := bmp.Width;
      c2 := bu;
      for i := 10 to X2 - 1 do
      begin
        c1 := au;
        currPixel := p;
        inc(currPixel, i);
        for j := 0 to Y2 - 1 do
        begin
          z1 := 0;
          z2 := 0;
          Count := 0;
          // count is deep of iteration of the mandelbrot set
          // if |z| >=2 then z is not a member of a mandelset
          while (((z1 * z1 + z2 * z2 < 4) and (Count <= 50))) do
          begin
            tmp := z1;
            z1 := z1 * z1 - z2 * z2 + c1;
            z2 := 2 * tmp * z2 + c2;
            Inc(Count);
          end;
          // The color depends on the number of iterations
          hue := count / 50;
          saturation := 0.6;
          value := 0.5;
          currPixel^ := TColor(HSLtoRGB(hue, saturation, value));
          c1 := c1 + X;
          dec(currPixel, bytesPerLine);
        end;
        c2 := c2 + Y;
      end;
    end;

     


  9. 18 minutes ago, misc_bb said:

    Not really my intention to bypass. But basically we just want to create the svg file directly using the svg code

    OK, so if I understand you correctly, you're wanting to create SVG files but use ImageEN to read and render them.

    My strong recomendation is to create SVGs in UTF-8 format. SVGs were initially designed for web display and it's very rare to find an SVG file that isn't UTF-8 encoded (and just about everything web related is UTF-8). HTHs.

     


  10. 46 minutes ago, misc_bb said:

    We are currently dealing with rendering SVG images dynamically and we want to render the SVG using the svg code. Reading the svg code from a text file causing some text to be converted to something. What's the best approach for this one? Convert to UTF-8?

    Currently trying to create using a TMemoryStream then save the stream to a file via ImageEN but svg text/code gets converted to ascii.

    I'm somewhat confused by your questions. Your first sentence implies you're wanting to bypass the rendering done by ImageEN (mentioned in your fourth sentence). Is that your intention? If so, are you intending to write your own SVG parser and renderer?


  11. 54 minutes ago, misc_bb said:

    I realized this was only a mere change of format maybe that's why the text layers were not considered

    Actually I forgot to mention 😱, you have to load some fonts before they can be rendered in Image32 (and SVG files only very rarely contain font resources).

    Image32 reads TrueType fonts both directly from files or indirectly through the OS as demo'ed in SVG101 ...

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      ...
      FontManager.Load('Arial');
      FontManager.Load('Arial Bold');
      FontManager.Load('Arial Italic');
      FontManager.Load('Arial Bold Italic');
      FontManager.Load('Times New Roman');
      FontManager.Load('Times New Roman Bold');
      FontManager.Load('Times New Roman Italic');
      FontManager.Load('Times New Roman Bold Italic');

    and make sure you add Img32.Text to your uses clause. Also, you don't need to load a whole lot of fonts, just the ones that you'll need.

     

    More info here: http://www.angusj.com/delphi/image32/Docs/Units/Img32.Text/_Body.htm

     

    54 minutes ago, misc_bb said:

    How about without going through an ImagePanel will it still work?

    You certainly don't need ImagePanel, that's just useful for displaying images on a form. You can just save images to file if you wish.

    • Like 2

  12. 3 hours ago, misc_bb said:

    I maybe missing something?

    Hi misc_bb. Yes, I think you are 😜.

     

    Try modifying the SVG101 sample by adding a TSaveDialog control (with filters for PNG and JPG file types).

    Then make sure both Img32.Fmt.PNG and Img32.Fmt.JPG are in you uses clause.

    Finally add a mainmenu option with the following OnClick event:

    procedure TForm1.SaveAs1Click(Sender: TObject);
    begin
      if SaveDialog1.Execute then
        ImagePanel.Image.SaveToFile(SaveDialog1.FileName);
    end;

     

    test.png

     

    Edit: If the image has transparency, make sure you save it as in PNG format, otherwise you'll probably get a black background.

    Edit2: And if you don't want to add that extra bit of code, just make sure the image panel has focus (in SVG101) and click Ctrl+C. Then you can paste the result into your favorite image editor.


  13.  

    19 hours ago, Edwin Yip said:

    So I want to use your svg viewer, and would like to make the following changes

    Done.

    Also, there was a problem with the last update where I failed to upload a recent change in Img32.pas which caused problems in Img32.Layers. That's now fixed too.

    I've also made a minor update to the Layers301 sample application.

    https://sourceforge.net/projects/image32/files/

     

    layers301.thumb.png.fcb51a3105e702f94f1dc58647908aa7.png

     

    • Like 3

  14. 1 hour ago, Rollo62 said:

    Either a "FindById" function, or some kind of "Id" property in the TElement

    Try this ...

    unit Img32.SVG.Reader;
    ....
    
      TElement = class
      private
        ....
        fId             : UTF8String;
      public
        ....
        property Id: UTF8String read fId;
      end;
    
    procedure Id_Attrib(aOwnerEl: TElement; const value: UTF8String);
    begin
      aOwnerEl.fId := value; //ADD THIS LINE
      aOwnerEl.fReader.fIdList.AddObject(string(value), aOwnerEl);
    end;

     


  15. @Rollo62

    On 8/24/2021 at 9:07 PM, Rollo62 said:

    So my goal is to have a complex SVG, with certain layers, where I can control the rendering on-the-fly at runtime, like on/off changing color, etc..

    I've just uploaded to Image32's SourceForge repository another update to the SVG reader. The changes are primarily in anticipation of future animation but they should also allow you to dynamically change (most) element properties including fill and stroke colors, opacity etc.

     

    https://sourceforge.net/p/image32/code/ci/master/tree/source/

     

    Example:

     

    procedure ChangeNearBlackPenToNavy(element: TElement);
    var
      i: integer;
      dd: TDrawData;
    begin
      if (element.DrawData.strokeColor <> clInvalid) and 
        (element.DrawData.strokeColor <> clNone32) and
        (RgbToHsl(element.DrawData.strokeColor).lum < 5) then
      begin
        dd := element.DrawData;
        dd.strokeColor := clNavy32;
        element.DrawData := dd;
      end;
      //recursively call all children
      for i := 0 to element.ChildCount -1 do
        ChangeNearBlackPenToNavy(element[i]);
    end;
    //and to use the above procedure
    begin
      if not svgReader.LoadFromFile(fn) then Exit;
      //edit the loaded SVG elements
      ChangeNearBlackPenToNavy(svgReader.RootElement);
      //draw the edited SVG elements
      svgReader.DrawImage(ImagePanel.Image, true);
    end;

     

    • Like 1

  16. @Rollo62

    Thank you for the encouraging feedback. I'm glad Image32 is behaving as advertised 😁.

    9 hours ago, Rollo62 said:

    So my goal is to have a complex SVG, with certain layers, where I can control the rendering on-the-fly at runtime

    I'm afraid Image32's SVG support is pretty much read-only.

    There is an extremely basic SVG writer, that's separate from the reader, and really just proof of concept.

    The reader was designed for speed, not for editing as you've discovered.

    Regarding hashing:  I'm assuming it's faster than string comparing, which there are many, but honestly I haven't tested if it makes a difference and how much (and yes it does complicate the code).

    Regarding UTF8String: Just about every SVG is written in UTF-8 which given it was initially created for web graphics makes sense. So again for performance the file isn't converted to Unicode, and the XML parser just creates pointers into the UTF-8 stream.

     

    9 hours ago, Rollo62 said:

    My question is, if there is a simple way to access and control the SVG-tree on the fly

    No, not at the moment. I do intend to convert the reader to read-write at some stage. However I'm not sure when that will happen as I'm taking a much needed breather after spending a lot of time on this. I also have another project (my Clipper library) that's been stuck in a partial update for several years that's probably my next priority. If there was huge demand for read-write SVGs I might make that the higher priority but my perception is that reading SVGs is/was by far the bigger need.

    Cheers.

×