Recent

Author Topic: [SOLVED] Can't load BMP,RGB32 with BGRABitmap  (Read 13304 times)

molly

  • Hero Member
  • *****
  • Posts: 2345
Re: [SOLVED] Can't load BMP,RGB32 with BGRABitmap
« Reply #15 on: June 22, 2016, 07:42:03 am »
I was on holiday without my computer, so I just discovered this discussion.
Don't worry about that circular. Please enjoy your free time :-)

Thank you for having noticed the thread and discussing the topic.

Quote
I am not the kind of person to say "go f* yourself".
Sorry in case i have been too explicit with using those words.

In my experience with graphic related projects this specific topic seems to be a recurring discussion (usually a very boring one using the same arguments), and i assumed it could perhaps also be the case for bgrabitmap.

I did notice some other related posts here on the forums that seems to address the same topic (even though posters didn't always seem to have realized).

Quote
I suggest to add a flag to the LoadFromFile function a parameter AFixTransparentPixels that would be True by default, or to add a property to the TBGRABitmap object that would be similar.
Because such a change could lead up to 'problems' later on, it would imho be wise to have a solution that makes it perfectly clear to end-user that he/she is doing something out of the ordinary. In that regards and for me personally, i consider the workaround i posted as perfectly fine to 'overcome' the issue.

The only thing that kind of surprised me is that i wasn't able to read about this 'clearing' behaviour and/or documentation/examples mentioning a workaround so that end-users could address the issue themselves (but perhaps i haven't searched/looked hard enough)

Quote
What are your thoughts?
To be honest, i hadn't thought yet about what would be the best method/implementation for bgrabitmap to support the behaviour of 'loading' pixel-data when alpha is zeroed out. I'm simply not familiar/experienced with bgrabitmap and/or its (inner) workings.

Having a special flag for load method(s) seems to me the most end-user friendly and perhaps the most easiest to implement ?

Although in that case i think i would suggest to change the name of the flag "AFixTransparentPixels" as that could perhaps be interpreted wrongly as well ?

Maybe something like aClearTransparentPixelsByDefault, aClearTransParentPixelsOnLoad, or similar sounding would perhaps make things more clear ?

Of course if choosing the property solution then i would make the same suggestion for the name of the property.

That leaves me with the remark that i personally would feel more confident about making such decision when having (more) feedback from other (real) bgrabitmap users.

circular

  • Hero Member
  • *****
  • Posts: 3048
    • Personal webpage
Re: [SOLVED] Can't load BMP,RGB32 with BGRABitmap
« Reply #16 on: June 22, 2016, 03:49:27 pm »
@molly:
I suppose you were worried I would not reply or that we could not talk about the subject.

Quote
I did notice some other related posts here on the forums that seems to address the same topic (even though posters didn't always seem to have realized).
Which topic?

Quote
In that regards and for me personally, i consider the workaround i posted as perfectly fine to 'overcome' the issue.
Your workaround is fine to overcome the issue, however it would not load correctly some pictures that have RGB values for transparent pixels. I remember some PNG file that was like that.

Quote
The only thing that kind of surprised me is that i wasn't able to read about this 'clearing' behaviour and/or documentation/examples mentioning a workaround so that end-users could address the issue themselves (but perhaps i haven't searched/looked hard enough)
It is the first time as far as I can remember that this issue is raised. It is a bit technical and functions in BGRABitmap automatically clear the RGB components so users do not need to think about it in 99% of the case.

Regarding the documentation, it is mentioned in the definition of BGRAPixelTransparent that it is recommended that all channels would be zero. I have just added some comment for you in the definition of TBGRAPixel:
http://wiki.freepascal.org/BGRABitmap_Pixel_types#Pixel_types_and_functions

Quote
That leaves me with the remark that i personally would feel more confident about making such decision when having (more) feedback from other (real) bgrabitmap users.
Yes, that's why I prefer to get some feedback. However sometimes you don't get any input and you need to make a decision on what seems good for you.

@mercury:
Quote
Load any 32bit bmp will get a full black picture.
I guess the problem is that 32 bit format is not well defined. It is not possible to tell if the alpha value is to be ignored or not.

In my understanding, the 32 bit format is used sometimes to store 24 bit images where each pixel is stored in a DWORD. Hence the alpha channel is set to zero.

In fact, many programs do not handle the alpha channel at all, so that whatever the alpha value is, it is considered as opaque. However doing that prevents from loading images that actually include an alpha channel.

Arguably, this subject is specific to BMP file format, and clearing the RGB values for other formats is probably what everybody wants.

To avoid this problem, I recommend that a picture that is supposed to be 24bit per pixel would be saved using the 24bit file format or the 32bit format with BI_BITFIELDS. And only if there is an alpha channel to use the generic 32bit file format. However I understand one might receive data that is this format anyway.

Maybe the best would be to add a property to the BMP reader, to be able to set how to handle the alpha channel. So the loading code would be:
Code: Pascal  [Select]
  1. uses BGRAReadBMP;
  2.  
  3. var
  4.   bmp: TBGRABitmap;
  5.   writer: TBGRAWriterBmpMioMap;
  6.   reader: TBGRAReaderBMP;
  7. begin
  8.   w := 256;
  9.   h := 256;
  10.   reader := TBGRAReaderBMP.Create;
  11.   reader.TransparencyOption:= toOpaque;
  12.   bmp := TBGRABitmap.Create;
  13.   bmp.LoadFromFileUTF8('0.bmp', reader);
  14.   reader.Free;  
  15.   ...
  16.   bmp.Free;
  17. end;

What do you think?
Conscience is the debugger of the mind

molly

  • Hero Member
  • *****
  • Posts: 2345
Re: [SOLVED] Can't load BMP,RGB32 with BGRABitmap
« Reply #17 on: June 22, 2016, 05:19:54 pm »
Quote
Which topic?
The topic of loading a bitmap with bgrabitmap classes and being presented with a magical black empty box ;-)

Quote
however it would not load correctly some pictures that have RGB values for transparent pixels. I remember some PNG file that was like that.
You are correct in that the workaround is only to be used for 32-bit BMP bitmaps, and even then the 'dumb' value of 255 for alpha is incorrect (but at least gives the user an opportunity to modify alpha values as intended, directly after loading).

Quote
It is the first time as far as I can remember that this issue is raised. It is a bit technical and functions in BGRABitmap automatically clear the RGB components so users do not need to think about it in 99% of the case.
I assumed as such, and there is nothing wrong with the curent implementation of bgrabitmap. It is a choice probably made once by someone and which reflects the available specifications/documentation.

Quote
Regarding the documentation, it is mentioned in the definition of BGRAPixelTransparent that it is recommended that all channels would be zero. I have just added some comment for you in the definition of TBGRAPixel:
Yes, i had read that part of the documentation (before), and as such and as stated above i had already concluded that the behaviour encountered by OP is/was in line with the current implementation of bgrabnitmap as well as BMP specifications.

However, the behaviour that i was not expecting is that of a bitmap loader actually clearing the rgb values. In most common cases the loader would load the data and leave the rgb values as is. In which case user would and/or could perhaps expect the picture to be displayed correctly, but that would then simply be a wrong assumption. Only when alpha values are set correctly the picture would display on screen correctly.

The above with the exception of using a specific blitting operation that does not care about alpha values and blit/display rgb values regardless ;-)

The issue as discussed is that bgrabitmap currently does not expose/offer the user functionality to 'correct' this situation (other then overloading class methods/procedures to overcome the 'problem'). So, any improvement you are able to implement and/or would like to offer would be a good one :-)

Other than that, i would like to refrain from entering a (over)heated discussion on what should be considered right or what should be considered wrong.

In my book 32-bit bitmaps are relevant only when actually using alpha values. If not using correct alpha values, the program/user should write/store them as 24-bit bitmaps. And having read the rest of your post, i believe you think similar :-)

Thank you for having added the (extra) remark at the wiki concerning the clearing of the rgb values.

Quote
Maybe the best would be to add a property to the BMP reader, to be able to set how to handle the alpha channel. So the loading code would be:
Although the question wasn't addressed to me, so please consider it fwiw :-) i agree that placing bmp specifics into bmp reader would be a more logical solution.

mercury

  • Full Member
  • ***
  • Posts: 151
Re: [SOLVED] Can't load BMP,RGB32 with BGRABitmap
« Reply #18 on: June 23, 2016, 01:50:14 pm »
Maybe the best would be to add a property to the BMP reader, to be able to set how to handle the alpha channel.
I just want to make the program behavior like what most picture viewer or the web browser do. No mater such 32bit bmp which all alpha is 0 or bmp which has actual transparent property, it can load and display properly.

i agree that placing bmp specifics into bmp reader would be a more logical solution.
Sorry, I don’t agree with use a TFPCustomImageReader to load bmp. For that, you must check if the file is bmp format before load it.
And, I can’t make it work. (BGRABitmap 8.9.2, Lazarus 1.6.0, windows 8.1)
Code: Pascal  [Select]
  1. reader.TransparencyOption := toOpaque;
  2. Error: identifier idents no member "TransparencyOption"


The need expressed here is to get access to the data anyway. I suggest to add a flag to the LoadFromFile function a parameter AFixTransparentPixels that would be True by default, or to add a property to the TBGRABitmap object that would be similar.
I think this is the best way.

That’s my opinion. Thank you very much.



circular

  • Hero Member
  • *****
  • Posts: 3048
    • Personal webpage
Re: [SOLVED] Can't load BMP,RGB32 with BGRABitmap
« Reply #19 on: June 23, 2016, 02:51:08 pm »
@mercury:

I understand that you would like the program to display the BMP as most viewers would do.

Personally, I am worried about backward compatibility, so I would like to find a solution that would work in all cases.

It is possible to add an toAutodetect option so that if the BMP has all alpha set to zero, it would be considered as opaque instead. That would work in 99% of the cases. Then if someone wants to load an empty BMP, where all alpha is zero, they could use toTransparent option.

I know that it does not work yet, I am suggesting how it would be with such an option. Read again "Maybe the best would be to add a property to the BMP reader".

I am thinking about adding a set of options to be provided to the loading functions LoadFromFile* that would set the flags in the readers. That would make it easy for users.
Conscience is the debugger of the mind

mercury

  • Full Member
  • ***
  • Posts: 151
Re: [SOLVED] Can't load BMP,RGB32 with BGRABitmap
« Reply #20 on: June 23, 2016, 04:09:16 pm »
I am thinking about adding a set of options to be provided to the loading functions LoadFromFile* that would set the flags in the readers. That would make it easy for users.
I don't want use different readers to load different format. I like easiness. Set the options, then LoadFromFile for any format. :D

circular

  • Hero Member
  • *****
  • Posts: 3048
    • Personal webpage
Re: [SOLVED] Can't load BMP,RGB32 with BGRABitmap
« Reply #21 on: June 23, 2016, 05:38:40 pm »
Ok. I have added the property to the reader and also a parameter to LoadFromFile functions. It is on SVN and Git.

So you can load the BMP in "compatible mode" like that:
Code: Pascal  [Select]
  1.     var
  2.       bmp: TBGRABitmap;
  3.     begin
  4.       bmp := TBGRABitmap.Create;
  5.       bmp.LoadFromFileUTF8('0.bmp', [loBmpAutoOpaque]);
  6.       ...
  7.       bmp.Free;
  8.     end;

Note that using this option, if a BMP is supposed to be completely empty, it will be opaque instead.

The possible loading options are:
  • loKeepTransparentRGB: do not clear RGB channels when alpha is zero (not recommended)
  • loBmpAutoOpaque: use the toAuto value for Transparency option of BMP (for compatibility)
  • loJpegQuick: use speed load for JPEG (lower quality)

Using the BMP reader, the possible values for TransparencyOption are:
  • toTransparent: favors transparency (so that you can store a completely transparent image in a BMP)
  • toAuto: automatically makes the picture opaque if alpha is all set to zero (compatibility and at the same time allows to have transparency with BMP files in most cases)
  • toOpaque: always considers the picture to be transparent (could be useful if the alpha values are set to something but in fact the image is supposed to be opaque)

Note that those option applies only to 32bit format. Other formats are always opaque.
Conscience is the debugger of the mind

mercury

  • Full Member
  • ***
  • Posts: 151
Re: [SOLVED] Can't load BMP,RGB32 with BGRABitmap
« Reply #22 on: July 03, 2016, 05:06:19 am »
@circular
First of all, thank you very much.

I see you add support for ZenGL. (http://zengl.org/forum/index.php/topic,642.msg4266.html#msg4266) And move all bgrabitmap code to an independent folder. Will you make bgrabitmap become a full game engine? ZenGL’s author seems not continue work on it, maybe you can integrate bgrabitmap and ZenGL. It will be awesome to make game with bgrabitmap running on mobile device.

circular

  • Hero Member
  • *****
  • Posts: 3048
    • Personal webpage
Re: [SOLVED] Can't load BMP,RGB32 with BGRABitmap
« Reply #23 on: July 03, 2016, 01:13:31 pm »
You're welcome.

Regarding ZenGL + BGRABitmap, I am not sure what you suggest to do. You can already use BGRABitmap to generate textures that you can use in ZenGL and use the features of ZenGL.
Conscience is the debugger of the mind