Recent

Author Topic: Reading tBitmap data is extremely slow  (Read 425 times)

jollytall

  • Sr. Member
  • ****
  • Posts: 366
Reading tBitmap data is extremely slow
« on: September 15, 2024, 04:50:52 pm »
I load an external bitmap file.
Code: Pascal  [Select][+][-]
  1.   MyBitmap := tBitmap.Create;
  2.   MyBitmap.LoadFromFile(FileName);
This works. I also show it on the screen:
Code: Pascal  [Select][+][-]
  1.   Form1.Image1.Picture.Bitmap := MyBitmap;
If I want to change pixels in it, that also works reasonably fast (I read all the acceleration methods, but for the time being it is fast enough for me if I use BeginUpdate/EndUpdate):
Code: Pascal  [Select][+][-]
  1.   Form1.Image1.Picture.Bitmap.BeginUpdate(true);
  2.   for x := 0 to W - 1 do
  3.     for y := 0 to H - 1 do
  4.       Form1.Image1.Picture.Bitmap.Canvas.Pixels[x, y] := random($ff);
  5.   Form1.Image1.Picture.Bitmap.EndUpdate(false);
  6.  
However if I want to read the same data, it gets extremely slow. I would expect that reading data should be much faster as less range checking, etc. might be needed, but it is the opposite.
Code: Pascal  [Select][+][-]
  1.   Form1.Image1.Picture.Bitmap.BeginUpdate(true);
  2.   for x := 0 to W - 1 do
  3.     for y := 0 to H - 1 do
  4.       MyArray[x, y] := Form1.Image1.Picture.Bitmap.Canvas.Pixels[x, y];
  5.   Form1.Image1.Picture.Bitmap.EndUpdate(false);
I also tried to read it from the original bitmap, rather than the image, but it is the same speed:
Code: Pascal  [Select][+][-]
  1.   MyBitmap.BeginUpdate(true);
  2.   for x := 0 to W - 1 do
  3.     for y := 0 to H - 1 do
  4.       MyArray[x, y] := MyBitmap.Canvas.Pixels[x, y];
  5.   MyBitmap.EndUpdate(false);

How could I make the read as fast as the write? I do not need faster than that, but currently it is like 50-100 times slower.

Thaddy

  • Hero Member
  • *****
  • Posts: 16196
  • Censorship about opinions does not belong here.
Re: Reading tBitmap data is extremely slow
« Reply #1 on: September 15, 2024, 05:16:42 pm »
You can save the bitmap to file or e.g. a memory stream, which is much faster than writing pixels to an array. That is slow.
Or use assign() with another bitmap.
« Last Edit: September 15, 2024, 05:35:15 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

jollytall

  • Sr. Member
  • ****
  • Posts: 366
Re: Reading tBitmap data is extremely slow
« Reply #2 on: September 15, 2024, 05:37:46 pm »
Sorry, I don't get it. Writing numbers to my MyArray is fast (fast enough). I manipulate much larger arrays and that is OK. Writing pixels from my array to the bitmap, is also fast enough. The problem is with reading the pixels.
How can I make that faster by writing the bitmap to a file? Btw. the bitmap is already in a file, but I do not want to write a bitmap container unpacking program.

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: Reading tBitmap data is extremely slow
« Reply #3 on: September 15, 2024, 05:42:10 pm »
Use the RAWimage of the bitmap, it's a direct memory image and thus does not use the GDI calls.
The only true wisdom is knowing you know nothing

wp

  • Hero Member
  • *****
  • Posts: 12471
Re: Reading tBitmap data is extremely slow
« Reply #4 on: September 15, 2024, 08:23:58 pm »
Find in the attachment a small test project which converts the Lazarus cheetah image to a 2D array of TColor values. The first button does it by accessing the Canvas.Pixels of the bitmap, it takes about 2.3 seconds in my system. The second button converts the bitmap to a LazIntfImage which is independent of the OS calls; now reading is much faster, it only takes about 0.03 seconds to get the pixels colors into the array.

Direct memory access would even be a bit faster, however has the disadvantage that the exact memory layout of the pixels must be known (bits per pixel, order for R/G/B bytes, memory needed for each color channel, etc) - TLazIntfImage determines that automatically.

jollytall

  • Sr. Member
  • ****
  • Posts: 366
Re: Reading tBitmap data is extremely slow
« Reply #5 on: September 16, 2024, 08:54:43 pm »
Thanks, I will try it in my system.
In the meantime I did cross compilation from Linux to Win64, and the routine that took like 20-30 seconds on Linux is <1s on Windows. I guess it can have something with the data format of my bmp file (created by Gnome Paint). Maybe the byte alignment is different when it is loaded into Linux or when the same Linux/Gnome/Paint generated file is read into a windows exe. My users are in Win64 and the speed is no issue there.
Very strange.

 

TinyPortal © 2005-2018