bgrabitmap / bgrabitmap

📜 BGRABitmap graphics library made with Lazarus (Free Pascal).
https://bgrabitmap.github.io/
191 stars 31 forks source link

Maintain the "bit format" of a file between reading and subsequent writing #231

Open maxm74 opened 6 months ago

maxm74 commented 6 months ago

Given that I don't know the package's class structure in depth.

Is there a way to maintain the "bit format" of a file between reading and subsequent writing? For example: I read a GrayScale Bitmap in TBGRABitmap I work there when I write the Bitmap to a file I get a RGB color format

It would be interesting to keep some information (such as bits per pixel, etc) and allow the user to save it using the same "bit format" (something like TBGRASavingOption = (soKeepBitFormat)).

maxm74 commented 6 months ago

doing other tests I noticed that when doing operations like Rotate, GetPart, etc the Palette is not copied into the new image

circular17 commented 6 months ago

Hi @maxm74,

The idea is appealing to save in the save format as the original image. Adding this information may not be straightforward because of the various ways data can be saved, either regarding bit depth, byte order, colorspace etc. I imagine that it would make sense to gather all those possible format information, for example storing it into the TQuickImageInfo structure. This structure could be stored as a property of a bitmap called OriginalFormat. This property would be filled when loading an image and copied when calling CopyPropertiesTo.

For now, there is not a consistent behavior regarding copy of properties with Rotate*, GetPart, etc. Maybe the simpler, not strictly backward compatible though, would be to add a boolean parameter ACopyProperties, with a default value matching as closely as possible the current behavior.

For now, the Rotate* function don't copy much of the properties except the code you've added. So probably we can assume that currently ACopyProperties is false. Currently only resolution is copied but I agree it would make sense to copy other properties. As a sidenote, I noticed something counter-intuitive in CW and CCW, the X and Y resolution needing to be exchanged in my view:

  result.ResolutionUnit:=Self.ResolutionUnit; { #note -oMaxM : Maybe done in InternalNew? }
  result.ResolutionX:=Self.ResolutionX; // if rotated 90º then that would be Y here
  result.ResolutionY:=Self.ResolutionY;

About copying the palette, I don't know if this can be considered as a property to copy. If that's the case, let's add it in the CopyPropertiesTo method, otherwise we may add another parameter ACopyPalette to the functions parameters when relevant. For simplicity, and because I suppose Palette is not much used yet, the first option seems the most straightforward, without breaking to much existing code.

Whatever we choose to do, this we need to mention it when publishing the new version, for people making use of those properties.

Once we have settled on something with those properties, I find the idea of a save option soKeepBitFormat to be a good choice, letting users choose whether to use the previous format. Maybe we can call it soKeepOriginalPixelFormat to say we want to use original bit depth, byte order, colorspace, etc.

Thanks for your valuable input.

Warm regards

maxm74 commented 6 months ago

I'll work on it after the holidays, I need to recharge my batteries...

circular17 commented 6 months ago

Sure, enjoy the holidays!

circular17 commented 4 months ago

Hi @maxm74

I've created a new dev branch called dev-formatconfig with the BGRAReadWriteConfig unit you've added. We may refactor things. Having a separate branch will give use time to think about it before we publish something.

Regards