Recent

Author Topic: Setting TBitmap.PixelFormat is broken?  (Read 2486 times)

TRon

  • Hero Member
  • *****
  • Posts: 2435
Re: Setting TBitmap.PixelFormat is broken?
« Reply #15 on: February 02, 2023, 05:20:35 am »
TBitmap has many uses, GUI is just one (the most common) of them.
GUI is /the only/ use for TBitmap class. You can't use the class without a widget back-end.

Quote
Pixelformat is a writable property (like in Delphi) and there is also this todo-comment in TCustomBitmap.SetPixelFormat(): "{$note todo copy image into new format }", for data conversion.
That comment has been there for over 2 decades now  (the original comment was written a bit different though, and in another file).

Let's assume for a moment that you are right and that TBitmap must/should be able to convert graphical data from 64-bit to 2 bit (just to name an arbitrary example), then how would that be converted and more importantly how is that format internally stored  ? Do keep multi-platform support in mind.

If you have found an answer to that then try and see what implementations are already available to do such conversions and have their own internal storage formats that are cross-platform compatible. Hint: Have a look at fcl-image and bgrabitmap.

There is absolutely no need whatsoever to abuse the TBitmap class with even more confusing functionality.

nanobit

  • Full Member
  • ***
  • Posts: 160
Re: Setting TBitmap.PixelFormat is broken?
« Reply #16 on: February 02, 2023, 11:00:36 am »
Again, the writable TBitmap.PixelFormat is possible, and within the current design.
TBitmap uses internally TRawImage (interface-independent) and the subsequent Handles (interface-dependent) support multiple formats too, including a fallback (Default) format if needed, within the range of TPixelFormat. TPixelFormat is Delphi compatible and declares only a small common set of formats. More support is not required by documentation.

domasz

  • Sr. Member
  • ****
  • Posts: 423
Re: Setting TBitmap.PixelFormat is broken?
« Reply #17 on: February 04, 2023, 12:20:37 am »
Let's assume for a moment that you are right and that TBitmap must/should be able to convert graphical data from 64-bit to 2 bit (just to name an arbitrary example),
[..]
There is absolutely no need whatsoever to abuse the TBitmap class with even more confusing functionality.

TBitmap comes from Delphi and in Delphi it's a super popular thing to do to convert internal bitness of TBitmap. Quite likely most graphic routines written in Delphi won't work correctly until this is fixed.
And here's how it is used very often. It's simple and really fast:


Code: Pascal  [Select][+][-]
  1. var P: PByteArray;
  2.       x,y: Integer;
  3. begin
  4.   Bmp := TBitmap.Create;
  5.   Bmp.LoadFromFile('test.bmp');
  6.   Bmp.PixelFormat := pf32bit; //now it doesn't matter if test.bmp was 24bpp, 8bitt, 1bpp or 32bpp. It is now 32bpp. Always, so we can safely do the below:
  7.  
  8.   for y:=0 to Bmp.Height-1 do begin
  9.    P := Bmp.Scanline[y];
  10.  
  11.    for x:=0 to Bmp.Width-1 do begin
  12.      P[4*x    ] := 255; //B
  13.      P[4*x+1] := 255; //G
  14.      P[4*x+2] := 255; //R
  15.      P[4*x+3] := 255; //A or X
  16.    end;
  17.   end;
  18. end;

TRon

  • Hero Member
  • *****
  • Posts: 2435
Re: Setting TBitmap.PixelFormat is broken?
« Reply #18 on: February 04, 2023, 01:44:30 pm »
TBitmap comes from Delphi
Small correction: the class implementation by Delphi is an encapsulation around the MS/Windows bitmap. All functionality of that class originates from Windows.

Quote
...and in Delphi it's a super popular thing to do to convert internal bitness of TBitmap. Quite likely most graphic routines written in Delphi won't work correctly until this is fixed. And here's how it is used very often. It's simple and really fast:
I am aware of how that works /for Delphi/ icw /windows/. But please do feel free to ignore the cross-platform and underlying hw compatibility because ... who cares ?

The current Lazarus bitmap implementation is already an abomination because of these restrictions.

It took only 20 years to get to this point so who knows ? Perhaps it will be implemented in another 2 weeks ?  :)

domasz

  • Sr. Member
  • ****
  • Posts: 423
Re: Setting TBitmap.PixelFormat is broken?
« Reply #19 on: February 04, 2023, 02:05:07 pm »
But please do feel free to ignore the cross-platform and underlying hw compatibility because ... who cares ?

The current Lazarus bitmap implementation is already an abomination because of these restrictions.

It took only 20 years to get to this point so who knows ? Perhaps it will be implemented in another 2 weeks ?  :)

Here's one way how to solve the problem- make TBitmap work just like in Delphi but with a notice it's platform-specific and if a programmer wants portability then should switch to TBGRABitmap or something else.
I have been using Delphi since Delphi 3. I recently switched to Lazarus and this damn PixelFormat is the only thing I am not happy about. This clearly shows Lazarus is amazing. There's more problems I have with Delphi today (like Unicode and it's GUI and how slow it is).

nanobit

  • Full Member
  • ***
  • Posts: 160
Re: Setting TBitmap.PixelFormat is broken?
« Reply #20 on: February 04, 2023, 02:34:41 pm »
It took only 20 years to get to this point so who knows ? Perhaps it will be implemented in another 2 weeks ?  :)

Many fields in FPC/Lazarus have only a single contributor or less,
so decades of non-work don't say much about the difficulty yet.

The implementation of TBitmap.PixelFormat is just unfinished.
But indeed, there is no quick solution here, but it's possible with many incremental improvements under the umbrella of the current design.
In SetPixelFormat(): Before converting to a new PixelFormat, the function needs to query if the destination format is possible. And only then convert (between TRawImage objects).

The first enhancement (prerequisite) would be that widgetsets support more formats in:
function TWidgetSet.rawImage_queryDescription(): boolean;
AFAIK, all widgetsets could be extended to allow (1,4,8,16,24,32) for TRawImage.
The first step would implement the most popular formats (nonpalette: 24, 32).
Finally, also TRawImageQueryFlag would need to be extended by a few bitness values (default is used if bitness is unrequested or unsupported).

As parttime WinApp developer I have no time/need/testsystems for this, but a more complete TBitmap would be useful for many.

 

TinyPortal © 2005-2018