Recent

Author Topic: Fast loading of images  (Read 3756 times)

wp

  • Hero Member
  • *****
  • Posts: 11910
Re: Fast loading of images
« Reply #15 on: April 12, 2023, 05:12:15 pm »
Anyway i suppose TJpegImage is just for jpeg images, what if in the future i want to use png or bmp or webp?
Yes, it's what its name says... If you need a multiformat loader you should use TPicture. But then you are tied to the registered formats and their readers, so that you cannot optimize them. Some third-party libraries register their readers in the LCL and replace the built-in formats, however. Or you read the first few bytes from each file and determine the file format from the file header and then select the appropriate reader class yourself - distinguishing between jpg, png or bmp is really easy. I don't know much about BGRABitmap, maybe it has a multiformat reader.

VisualLab

  • Sr. Member
  • ****
  • Posts: 306
Re: Fast loading of images
« Reply #16 on: April 12, 2023, 05:13:17 pm »
But every single time it crashes on that line. Anyway i suppose TJpegImage is just for jpeg images, what if in the future i want to use png or bmp or webp?

PNG -> class TPortableNetworkGraphic
BMP -> class TBGRABitmap

phoenix27

  • Jr. Member
  • **
  • Posts: 90
Re: Fast loading of images
« Reply #17 on: April 12, 2023, 05:14:52 pm »
@hukka is it fast GDI+ ?. I'm on windows 7, so i could try. How would i load images with GDI+?

phoenix27

  • Jr. Member
  • **
  • Posts: 90
Re: Fast loading of images
« Reply #18 on: April 12, 2023, 05:25:04 pm »
@Visual Lab i agree perfectly with you. That's why i said in a previous post that javascript it's just a scripting language which allows you to interact with the browser platform just like lua allows you to simply script a game. But lua is not c++,  in which the game was created.

phoenix27

  • Jr. Member
  • **
  • Posts: 90
Re: Fast loading of images
« Reply #19 on: April 12, 2023, 05:41:39 pm »
@wp i noticed that TPicture,  when the extension of the file its different from the actual format,  raises a 'wrong format' error, whereas TBGRABitmap doesn't

wp

  • Hero Member
  • *****
  • Posts: 11910
Re: Fast loading of images
« Reply #20 on: April 12, 2023, 05:57:39 pm »
@wp i noticed that TPicture,  when the extension of the file its different from the actual format,  raises a 'wrong format' error, whereas TBGRABitmap doesn't
Yes it would be fine if there were an option to bypass the exception in such a case. But you always can load the file into the TPicture via a stream so that the extension is unknown:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   stream: TStream;
  4. begin
  5.   stream := TFileStream.Create('test.bmp', fmOpenRead);  // 'test.bmp' is a 'png' image renamed to 'bmp'.
  6.   try
  7.     stream.Position := 0;
  8.     Image1.Picture.LoadFromStream(stream);
  9.   finally
  10.     stream.Free;
  11.   end;
  12. end;

hukka

  • New Member
  • *
  • Posts: 30
    • Github
Re: Fast loading of images
« Reply #21 on: April 12, 2023, 06:01:07 pm »
@hukka is it fast GDI+ ?. I'm on windows 7, so i could try. How would i load images with GDI+?

Snippet from my image viewer:

Code: Pascal  [Select][+][-]
  1. uses Windows, GdiPlus, ActiveX;
  2.  
  3. function GDILoadImage(Stream: TStream): TBGRABitmap;
  4. var
  5.         StreamAdapter: IStream;
  6.         BitmapData: TGPBitmapData;
  7.         rec: TGPRect;
  8.         gdipBitmap: GpBitmap;
  9.         Y: Integer;
  10.         PP: Pointer;
  11. begin
  12.         Result := nil;
  13.         try
  14.                 StreamAdapter := TStreamAdapter.Create(Stream);
  15.                 try
  16.                         gdipBitmap := nil;
  17.                         if GdipCreateBitmapFromStream(StreamAdapter, gdipBitmap) <> Ok then Exit;
  18.                         rec.X := 0; rec.Y := 0;
  19.                         GdipGetImageWidth(gdipBitmap, UINT(rec.Width));
  20.                         GdipGetImageHeight(gdipBitmap, UINT(rec.Height));
  21.                         if GdipBitmapLockBits(gdipBitmap, @rec,
  22.                                 [ImageLockModeRead], PixelFormat32bppARGB, BitmapData) = Ok then
  23.                         begin
  24.                                 with BitmapData do
  25.                                 begin
  26.                                         Result := TBGRABitmap.Create(Width, Height);
  27.                                         PP := Scan0;
  28.                                         for Y := 0 to Height-1 do
  29.                                         begin
  30.                                                 Move(PP^, Result.ScanLine[Y]^, Width*4);
  31.                                                 Inc(PP, Stride);
  32.                                         end;
  33.                                 end;
  34.                                 GdipBitmapUnlockBits(gdipBitmap, BitmapData);
  35.                         end;
  36.                         GdipDisposeImage(gdipBitmap);
  37.                 finally
  38.                         StreamAdapter := nil;
  39.                 end;
  40.         except
  41.                 FreeAndNil(Result);
  42.         end;
  43. end;
  44.  
  45. function GDILoadImage(const Filename: String): TBGRABitmap;
  46. var
  47.         S: TFileStream;
  48. begin
  49.         Result := nil;
  50.         if not FileExists(Filename) then Exit;
  51.  
  52.         S := TFileStream.Create(Filename, fmOpenRead);
  53.         try
  54.                 Result := GDILoadImage(S);
  55.         finally
  56.                 S.Free;
  57.         end;
  58. end;
  59.  

« Last Edit: April 12, 2023, 06:04:51 pm by hukka »

phoenix27

  • Jr. Member
  • **
  • Posts: 90
Re: Fast loading of images
« Reply #22 on: April 13, 2023, 02:54:56 am »
Thank you hukka, ill try the code.
I can say i' m satisfied. I put 3 threads at work and now it works like a charm, it loads all the images in less than 3 seconds. It's perfect for me. About my app in electron, i have forgotten a couple of things(i coded it a while ago). First of all i load only the images in the visible area and i load the rest incrementally while scrolling down. But more importantly, javascript has only one thread, so you cannot use multi-threading, but it has a cool feature called the event-loop(i think it's called like that), which means that I/O operations(like the loading of images, net or database connections and so on) happen by default not in the main thread(like it is for free pascal and most languages and that's why you need multi threading) but somewhere else and when the process ends you get notified through the use of callbacks. So we could say that javascript is non-blocking or async by nature. That's why it looks so smooth. Now i remember that when i loaded all the images at once there was a noticeable delay, although it is non-blocking!! That's why i decided to load only the images in the visible part of the app!

balazsszekely

  • Guest
Re: Fast loading of images
« Reply #23 on: April 13, 2023, 07:53:48 am »
@VisualLab
Fair enough. I'm not familiar with the loading mechanism. My point is javascript gets a lot of love and attention pascal not so much.

@phoenix27
Quote
I put 3 threads at work and now it works like a charm, it loads all the images in less than 3 seconds. It's perfect for me.
It's not good enough! You wanted to prove that pascal is faster then a scripting language. Here is your chance.   :D
Now seriously, you should try @hukka's method, it's really fast(windows only though). Please do the following:
1. Install GDIPlus from OPM(just added)
2. Install BGRABitmap if needed
3. Compile then run attached project
4. Download sample jpg image(30 Mb) from https://sample-videos.com/download-sample-jpg-image.php
At my side the 30 Mb image is loaded in 0.663 sec, which is ~5 times faster then the native solution presented by @wp in reply #5. More over it can load many image formats not just jpgs. Combine this method with your threaded solution and tell us the result. Since image processing is a CPU intensive task, it makes no sense to start more threads then your CPU/Core count. Usually 3 threads are not enough though.

@hukka
Very nicely done! 

« Last Edit: April 13, 2023, 08:19:13 am by GetMem »

domasz

  • Sr. Member
  • ****
  • Posts: 434
Re: Fast loading of images
« Reply #24 on: April 13, 2023, 10:14:09 am »
While Javascript is single-threaded, the web browser (Electron, Firefox, Chrome...) is not. It uses your CPU, GPU and lots of RAM for caching.
Javascript is not decoding images, the browser is. And it downloads and decodes images using many threads and many internet connections.

balazsszekely

  • Guest
Re: Fast loading of images
« Reply #25 on: April 13, 2023, 10:44:12 am »
@domasz
Quote
While Javascript is single-threaded, the web browser (Electron, Firefox, Chrome...) is not. It uses your CPU, GPU and lots of RAM for caching.
Javascript is not decoding images, the browser is. And it downloads and decodes images using many threads and many internet connections.
OK! Then let's forget about Javascript for a minute and compare the mighty browser(I suppose the rendering engine is coded in c++ ) with @hukka's example. Tested with Firefox 112.0(64 bit) vs. Lazarus Trunk/FPC 3.2.2(64 bit) and the results are very similar, Firefox it's slightly faster but not by much, tested with the 30 Mb jpeg(see above).

PS: Is pascal a good programming language? According to John Carmack it is: https://youtu.be/I845O57ZSy4?t=5743  :)
PS: Also about javascript(LMAO): https://www.youtube.com/watch?v=I845O57ZSy4&t=1115s
« Last Edit: April 13, 2023, 11:16:39 am by GetMem »

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2049
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Fast loading of images
« Reply #26 on: April 13, 2023, 11:23:42 am »
@GetMem, cool your loading method! I compared against ImageMagick, yours beat it 3x faster!
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

balazsszekely

  • Guest
Re: Fast loading of images
« Reply #27 on: April 13, 2023, 11:33:16 am »
@GetMem, cool your loading method! I compared against ImageMagick, yours beat it 3x faster!
Thank you, but all credits goes to @hukka. I only created a small demo application according to the code posted by him.
« Last Edit: April 13, 2023, 11:37:33 am by GetMem »

loaded

  • Hero Member
  • *****
  • Posts: 825
Re: Fast loading of images
« Reply #28 on: April 13, 2023, 01:00:24 pm »
The Google Picasa program is the expert in this business.
It makes loading, viewing and zooming the image surprisingly fast.
In fact, it would be great if the experts of the business examine and analyze this software.
Check out  loaded on Strava
https://www.strava.com/athletes/109391137

domasz

  • Sr. Member
  • ****
  • Posts: 434
Re: Fast loading of images
« Reply #29 on: April 13, 2023, 01:20:06 pm »
I tested this lib a while ago and was the fastest JPEG decoder for Delphi. But won't compile in Lazarus:
http://www.marktg.com/jpegdec/

 

TinyPortal © 2005-2018