Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transparency in the BMP image format #717

Closed
Skillkiller opened this issue Nov 28, 2022 · 10 comments
Closed

Transparency in the BMP image format #717

Skillkiller opened this issue Nov 28, 2022 · 10 comments

Comments

@Skillkiller
Copy link

Hello,
is it possible to store a BufferedImage with transparency in the BMP image format? With 32 bits per pixel this information should be storable. I also don't need a fine gradation of transparency but only is transparent or not.

I need to save it in a directly modifiable format because the image is too large for the memory of the creating program and the program assembles the image piece by piece.

@haraldk
Copy link
Owner

haraldk commented Nov 28, 2022

Yes, it's possible.

Unfortunately software support for transparency in BMP is variable, but I think most "serious" software should support it. My BMPImageReader should support both the "real" (using BI_ALPHABITFIELDS) and "fake" transparency options.

I assume you want to write your own BMP writer, then the best option is probably to write one of the more recent DIB headers, that contains alpha masks (BI_ALPHABITFIELDS) , and set the masks to full 8 bit range, to match a BufferedImage.TYPE_INT_ARGB or TYPE_4BYTE_ABGR.

There's a lot of good information in the Wikipedia article on BMP.

Other options could be to write uncompressed TGA or TIFF format. The PAM format (an evolution of PBM/PGM/PPM that also supports alpha, using TUPLTYP RGB_ALPHA) would also work I think.

@haraldk haraldk changed the title Ttransparency in the BMP image format Transparency in the BMP image format Nov 28, 2022
@haraldk
Copy link
Owner

haraldk commented Nov 28, 2022

Found your SO question, which indicates that you want to write the BMP using the TwelveMonkeys library... We do support transparency in BMP, currently only using TYPE_4BYTE_ABGR.

But then I'm afraid I don't understand the following:

I need to save it in a directly modifiable format because the image is too large for the memory of the creating program and the program assembles the image piece by piece.

Could you elaborate on this, perhaps even show code or pseudo-code?

If you want to write a BufferedImage using ImageIO, that indicates you have enough memory to keep everything in memory (as that is what BufferedImage does)...

@Skillkiller
Copy link
Author

Thank you for your reply. You are right, of course, and my question is not clear. Currently I use the BigBufferedImage class from MiklosPathy which keeps only parts of the image in memory and swaps the remaining parts to a temporary file. Not perfect and also from the performance everything else than good but with pictures which have 36000x36000 dimensions not differently possible.

My original plan was to create a big BufferedImage empty and save it to disk. After that I wanted to replace single parts of the image with ImageIO. For this I found this SO question.
First I wanted to save the images in PNG format but then the pixel replacement is not supported. Therefore I wanted to change to the BMP format, which apparently does not have a writer in ImageIO for Alpha.

@haraldk
Copy link
Owner

haraldk commented Nov 28, 2022

Hmmm...

That BigBufferImage class reminds me of something I made some time ago... 😀

Well, our BMPImageWriter does actually support BMP with alpha.. However, it only supports TYPE_4BYTE_BGRA at the moment. I just added support for TYPE_INT_ARGB as well, however, your images will all be TYPE_CUSTOM I think. So it won't work. I need to look if we could also support more types. And in any case, it does not support replacePixels (not many writers do).

But... If your huge image is already on disk... Why do you want to write an empty image to disk, and then manipulate using ImageIO? I believe it would be faster/easier to just copy tiles off the BigBufferImage instance into a normal BufferedImage and then set these tiles back. And write the entire big image to disk when done. In any format you like and that supports such image sizes.

Another option could be to just create a "fixed" header in BMP (or TGA/TIFF/PAM or other uncompressed format) and memory map the entire image data section and create a BufferedImage (or RenderedImage) similar to what BigBufferImage does. Shouldn't be that hard... Then you could just manipulate that image, and when done, the image would already be written... 😀

@tmccombs
Copy link

BMPImageReader should support both the "real" (using BI_ALPHABITFIELDS) and "fake" transparency options.

Do I (as a user of the twelvemonkeys API) need to do anything special when reading the BMP in order to get the support of "fake" transparency?

@tmccombs
Copy link

I have a bmp file (unfortunately github won't let me upload it), that has the following out put form imagemagick identify --verbose:

Image: image1.bmp
  Format: BMP3 (Microsoft Windows bitmap image (V3))
  Class: DirectClass
  Geometry: 137x86+0+0
  Units: PixelsPerCentimeter
  Colorspace: sRGB
  Type: GrayscaleAlpha
  Base type: Undefined
  Endianess: Undefined
  Depth: 8-bit
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit
    alpha: 8-bit
  Channel statistics:
    Pixels: 11782
    Red:
      min: 0  (0)
      max: 255 (1)
      mean: 67.0306 (0.262865)
      standard deviation: 107.995 (0.423508)
      kurtosis: -0.683889
      skewness: 1.1153
      entropy: 0.264371
    Green:
      min: 0  (0)
      max: 255 (1)
      mean: 67.0306 (0.262865)
      standard deviation: 107.995 (0.423508)
      kurtosis: -0.683889
      skewness: 1.1153
      entropy: 0.264371
    Blue:
      min: 0  (0)
      max: 255 (1)
      mean: 67.0306 (0.262865)
      standard deviation: 107.995 (0.423508)
      kurtosis: -0.683889
      skewness: 1.1153
      entropy: 0.264371
    Alpha:
      min: 0  (0)
      max: 255 (1)
      mean: 95.5188 (0.374584)
      standard deviation: 117.165 (0.459472)
      kurtosis: -1.61215
      skewness: 0.558641
      entropy: 0.378234

but twelvemonkeys 3.9.4 doesn't seem to detect the transparency.

@tmccombs
Copy link

After inspecting the image header, it looks like the

size of the DIB is 40 ( BITMAPINFOHEADER), the bits per pixel is 32, and the compression method is 0 (BI_RGB).

So it doesn't actually have any masks set, but I assume that the extra byte is meant as an alpha channel. This image displays with a transparent background in some programs such as imagemgaick display, and I think visio.

@haraldk
Copy link
Owner

haraldk commented Jan 18, 2023

Hmm.. I think I added to the confusion I wrote that about "fake" transparency support... Turns out we don't support this kind of fake "alpha" any more (we did at some point, but it turned out to be confusing). 😮 However, as I mentioned in #727, all the alpha data is there, if you want to "restore" it.

With the normal BITMAPINFOHEADER the only way to have transparency directly is using the BI_BITFIELDS/BI_ALPHABITFIELDS "compression" setting and specify masks.

PS: @tmccombs You can usually upload any kind of file if you zip compress it first, if you think that sample is important.

@Skillkiller
Copy link
Author

Again to the initial question from me. Thanks for your help @haraldk and also for your ideas. I had to pause the project for some time due to work but I was able to solve the problem as you said.

From my side the issue is ready to close. However, I don't want to interrupt the side conversation.
Thank you

@haraldk
Copy link
Owner

haraldk commented Jan 20, 2023

Thanks @Skillkiller!

I think we have the side conversation covered in a separate thread, so closing this.

@haraldk haraldk closed this as completed Jan 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants