9
$\begingroup$

I have a grayscale (one channel) image in Mathematica. How can I export it as a grayscale Bitmap?

Every single option I tried so far does not have an influence on the Bitmap exported using Export. If I export the image as PNG, Mathematica exports the grayscale image as expected.

Simple Example

Let's create a simple grayscale image:

image = Image[RandomReal[{0, 1}, {100, 150}]];

Simple export via:

Export["test.bmp",image];

shows exactly the problem mentioned above. Additional options like setting ColorSpace->"Grayscale" does not seem to have any effect. Any kind of color-conversion before doing the export did not work either, which is not surprising to me because the image already clearly carries the information that it is a grayscale image and export via

Export["test.png",image];

does export a grayscale PNG. Verification can for example be done by simple reimporting the ColorSpace Element of the exported image:

Import["test.bmp","ColorSpace"];
$\endgroup$
  • $\begingroup$ Can you post just the last 10 lines of code, to confirm my suspicion. $\endgroup$ – hieron Aug 20 '14 at 23:44
  • $\begingroup$ Have you already tried solutions from these?: (8818), (14949) $\endgroup$ – Mr.Wizard Aug 21 '14 at 7:34
  • $\begingroup$ @Mr.Wizard: Yes I did, without success. There is of course a chance that I was missing something. $\endgroup$ – Wizard Aug 21 '14 at 8:44
  • $\begingroup$ @bills: Yes I did, maybe it is a version 10 problem. I can confirm the problem with version 10 on a Windows and a Mac OS machine. $\endgroup$ – Wizard Aug 21 '14 at 8:45
  • $\begingroup$ Ok, definitely not a version 10 problem. Same behavior here on version 9 and I think the answers kind of explain it. $\endgroup$ – Wizard Aug 22 '14 at 8:03
5
$\begingroup$

You can obtain an 8-bit BMP by converting the image to an 8-bit representation:

Export["test.bmp", Image[image, "Byte"]]

Note that Import["test.bmp","ColorSpace"] will still return RGBColor, because an 8-bit BMP is still in the RGB color space (there is a color table which specifies an RGB color for each of the 256 possible pixel values - while it is very common for those 256 colors to be shades of gray, it is not guaranteed and it is incorrect to assume that an 8-bit BMP file always encodes a grayscale image).

You should instead use Import["test.bmp","ColorDepth"] to check that you have an 8-bit BMP.

$\endgroup$
  • $\begingroup$ But why then Import["test.png", "ColorSpace"] returns GrayLevel? Do you mean that PNG format supports grayscale color space while BMP supports only RGB colorspace? $\endgroup$ – Alexey Popkov Aug 21 '14 at 11:03
  • $\begingroup$ @AlexeyPopkov, yes that is my understanding. $\endgroup$ – Simon Woods Aug 21 '14 at 11:07
  • 1
    $\begingroup$ confirmed by file size check: FileByteCount[Export["test.bmp",Image[RandomReal[255,{1000,1000}],"Byte"]]]/1.*^6 -> 1.001 $\endgroup$ – george2079 Aug 21 '14 at 15:06
5
$\begingroup$

I wish to expand the answer by Simon Woods according to my current understanding.

The key point is that a BMP file normally does not contain a 2D array of RGB triplets but instead it contains a color table which lists all unique RGB triplets used in the image and assigns to each of them an index. The 2D array encoding the image contains only indices of colors, not colors themselves. The colors in the color table are specified as RGB triplets and due to this the colorspace is always RGB.

For example, a 8-bit BMP file can have no more than 256 unique RGB triplets in the color table with each having a 8-bit index. These triplets may all be shades of gray or may be not. One can also save such file as 32-bit BMP and then each entry in the color table will have 32-bit index. The information in such file will be the same but the size of the file will be much larger.

The colors in the color table are usually specified in the 4-byte per entry RGBA32 format. It means that it is possible to create huge number of grayscale images each having 256 distinct shades of gray being unique set of actual colors in RGBA32 format.

According to the Documentation page for BMP format, Mathematica supports the following Import elements for BMP:

  • "BitDepth" - number of bits used to encode a color channel in the file
  • "ColorDepth" - number of bits for each pixel
  • "ColorMap" - color reduction palette used in the file

Also, "Export creates a BMP file with indexed color when exporting color-mapped raster graphics or if the "ColorMap" element is specified."

$\endgroup$
  • $\begingroup$ After playing with this a good bit looking at file sizes, the only thing that actually produces a one byte per pixel file is @SimonWoods approach of converting the type to Byte before Export sees it. (That is to say the documented options simply do not work ) $\endgroup$ – george2079 Aug 21 '14 at 14:37
  • $\begingroup$ I agree: the documented options do not work for Export. The main purpose of my answer was to clear up the whole thing. And these long-standing bugs worth to be reported to the tech support. $\endgroup$ – Alexey Popkov Aug 21 '14 at 14:42
  • 1
    $\begingroup$ In fairness most of the opts are documented only under Import. This one point : " Export creates a BMP file with indexed color [... ] if the ColorMap element is specified. " seems to be just wrong however. $\endgroup$ – george2079 Aug 21 '14 at 14:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.