rust-bmp icon indicating copy to clipboard operation
rust-bmp copied to clipboard

Encoding 8bpp BMPs

Open golddranks opened this issue 8 years ago • 4 comments

Hi, I noticed that this library doesn't support encoding 8bpp BMPs. ( http://sondrele.github.io/rust-bmp/bmp/index.html )

Is this intentional, or just unimplemented? I'd like to save a 8bpp greyscale image, and BMP seems like an ideal format because of its simplicity.

golddranks avatar Jun 07 '16 06:06 golddranks

Hi!

The only reason this isn't supported is because it is unimplemented :) This library is mostly a result of needing to generate some simple images, and it was implemented because I couldn't find any other available library at that time.

A pull-request with 8-bit encoding would be very much appreciated! Or maybe I'll sit down in the near future to look into it :)

I was also about to recommend you to look at the PistonDevelopers/Image crate, but it seems like it only has support for BMP decoding.

sondrele avatar Jun 07 '16 06:06 sondrele

I checked the code and it seems that the pixel format is fixed to 3 channels. I guess we need to introduce another Image and Pixel types if we want in-memory representations of 1-channel images, since they aren't generic. But for the time being, just saving one channel of 3-channel image is enough for me.

But thinking from perspective of contributing to the Rust ecosystem, a general solution would be nice.

Then again, maybe it should be left as a concern for the Piston Image crate.

golddranks avatar Jun 07 '16 06:06 golddranks

A minimal solution for saving greyscale 8bpp BMPs would be some kind of an save_channel() function. What's your stance on the API design?

golddranks avatar Jun 07 '16 06:06 golddranks

Sorry for delayed answer, got caught up with work. But yeah, a general solution would be nice!

It's been a little while since I've looked at the BMP specification, but if I remember correctly 1, 4 and 8-bit BMP images must be encoded with a color palette. This color palette would consist of 255 different RGB colors for an 8-bit BMP image (and these colors would be linear between (0, 0, 0) and (255, 255, 255) for a gray scale image).

The decoder will look for a color palette when it decodes the image, and it will copy the RGB color from the palette at the respective index given by the 8-bit value in the image data when it constructs the Image struct. Thus, the in-memory representation will always be a 24 bpp BMP image after it has been decoded, and the color palette of the 1, 4, and 8-bit images gets lost in this process.

I'm not sure what the best way to construct an 8-bit image would be, but it seams like your suggestion about changing the Image and the Pixel type is the best one.

Maybe the Pixel can be an enum, somthing similar to this (Where 32, 8, 4, and 1 refers to how many bpp the image has.):

enum Pixel {
    RGB32(u8, u8, u8),
    RGB8(u8),
    RGB4(u8),
    RGB1(u8),
    GreyScale8(u8),
    GreyScale4(u8),
    GreyScale1(u8),
} //too verbose?

For this approach, the image would have to be an image of type pixel (Image<Pixel>) and it would need a new field for the color palette (Option<Vec>). We could also implement a couple of different constructors for the new types of images:

  1. RGB32 (like today's constructor)
  2. RGB8, 4, and 1 (a new constructor that takes width, height and a color palette)
  3. GrayScale8, 4, and 1 (a new constructor that takes width and height, but generates a gray scale color palette automatically)

This is just a rough outline, and it might be a bit of redundancy in here. What are your thoughts?

On Tue, Jun 7, 2016 at 8:50 AM, Pyry Kontio [email protected] wrote:

A minimal solution for saving greyscale 8bpp BMPs would be some kind of an save_channel() function. What's your stance on the API design?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/sondrele/rust-bmp/issues/21#issuecomment-224195117, or mute the thread https://github.com/notifications/unsubscribe/ABW26yuPuHmnD9aqejpD4uoNZYQZueEFks5qJRStgaJpZM4Ivlww .

sondrele avatar Jun 08 '16 08:06 sondrele