Monochrome images in ImageMagick?

How do you convert an image to monochrome using ImageMagicks's convert? Well it's not for the lack of options, but not all of them produces a file that is actually encoded as a 1 bit per pixel B/W monochrome file. According to the documentation we have:

  • -type Bilevel
  • -depth 1
  • -monochrome
  • -colors 2

And if your output is a png file then there is also:

  • -define png:bit-depth=1

Which purportedly must be used together with one of the other options.

Let us start by taking a look at the first one:

-type type

the image type.

Choose from: BilevelGrayscaleGrayscaleMattePalettePaletteMatteTrueColorTrueColorMatteColorSeparation, orColorSeparationMatte.

Normally, when a format supports different subformats such as grayscale and truecolor, the encoder will try to choose an efficient subformat. The -type option can be used to override this behavior. For example, to prevent a JPEG from being written in grayscale format even though only gray pixels are present, use.

$ convert bird.png -type TrueColor bird.jpg

Similarly, use -type TrueColorMatte to force the encoder to write an alpha channel even though the image is opaque, if the output format supports transparency.

Use -type optimize to ensure the image is written in the smallest possible file size.

From that description it surely sounds like that this should create a true monochrome image, right?

$ convert magick:wizard -type Bilevel type-bilevel.bmp
$ identify type-bilevel.bmp
type-bilevel.bmp BMP 480x640 480x640+0+0 8-bit sRGB 922KB 0.000u 0:00.002

8-bit sRGB? That doesn't sounds like monochrome to me. But at least the image is dithered:

type-bilevelSo what about the next one? The name surely sounds like it should be the right one, or…?

-depth value

depth of the image.

This the number of bits in a color sample within a pixel. Use this option to specify the depth of raw images whose depth is unknown such as GRAY, RGB, or CMYK, or to change the depth of any image after it has been read.

Doesn't says anything about whether it will have any influence on the output format. But let us try it:

$ convert magick:wizard -depth 1 depth-1.bmp
$ identify depth-1.bmp
depth-1.bmp BMP 480x640 480x640+0+0 8-bit sRGB 256c 177KB 0.016u 0:00.014

Nope, that didn't work either, but this time it got changed into a 256 entry palette based image apparently. It is also still a 3 channel rgb image, wich probably isn't surprising as we didn't tell it to change the colorspace:

depth-1So maybe we should change the colorspace too with -colorspace:

-colorspace value

Set the image colorspace.

Choices are:

   CMY          CMYK         Gray         HCL
   HCLp         HSB          HSI          HSL
   HSV          HWB          Lab          LCHab
   LCHuv        LMS          Log          Luv
   OHTA         Rec601YCbCr  Rec709YCbCr  RGB
   scRGB        sRGB         Transparent  XYZ
   YCbCr        YCC          YDbDr        YIQ
   YPbPr        YUV

To print a complete list of colorspaces, use -list colorspace.

So let us try with "Gray" colorspace:

$ convert magick:wizard -depth 1 -colorspace Gray depth-1-colorspace-gray.bmp
$ identify depth-1-colorspace-gray.bmp
depth-1-colorspace-gray.bmp BMP 480x640 480x640+0+0 8-bit sRGB 922KB 0.000u 0:00.001

Nope still RGB, and this time it didn't even bother dithering the image:depth-1-colorspace-gray

So what about -monochrome? Surely that should create a true monochrome image, right?

-monochrome

transform the image to black and white.

That was some beautifully useless documentation. So what happens this time?

$ convert magick:wizard -monochrome monochrome.bmp
$ identify monochrome.bmp
monochrome.bmp BMP 480x640 480x640+0+0 8-bit sRGB 922KB 0.000u 0:00.002

Not this either. But at least it decided to dither it this time:

monochrome

So what about the last one?

-colors value

Set the preferred number of colors in the image.

The actual number of colors in the image may be less than your request, but never more. Note that this a color reduction option. Images with fewer unique colors than specified by value will have any duplicate or unused colors removed. The ordering of an existing color palette may be altered. When converting an image from color to grayscale, it is more efficient to convert the image to the gray colorspace before reducing the number of colors. Refer to the color reduction algorithm for more details.

Nah, that only changes the number of colors, not the actual number of bits used… right?

$ convert magick:wizard -colors 2 colors-2.bmp
$ identify colors-2.bmp
colors-2.bmp BMP 480x640 480x640+0+0 1-bit sRGB 2c 38.5KB 0.000u 0:00.001

… 1-bit 2 colors?? Wat… How… I don't even… So, um, I didn't specify it should be greyscale, so what does it look like?

colors-2It did dither it this time. So we just have to specify the right colorspace:

$ convert magick:wizard -colors 2 -colorspace Gray colors-2-colorspace-gray.bmp
$ identify colors-2-colorspace-gray.bmp
colors-2-colorspace-gray.bmp BMP 480x640 480x640+0+0 8-bit sRGB 922KB 0.000u 0:00.002

Whaaaaaaaat? It didn't turn it black/white either which may not be that surprising (but contrary to the behavior when we used -depth 1):

colors-2-colorspace-graySo -colorspace Gray apparently has the side effect of turning the image into a 24-bit RGB image. Common sense is sitting in a corner crying right now. What if we swap the parameters?

$ convert magick:wizard -colorspace Gray -colors 2 colorspace-gray-colors-2.bmp
$ identify colorspace-gray-colors-2.bmp
colorspace-gray-colors-2.bmp BMP 480x640 480x640+0+0 1-bit sRGB 2c 38.5KB 0.000u 0:00.000

At least that made some kind of sense. The image still looks identical to the one above though. But that leads us to the conclusion that -monochrome -colors 2 probably should work:

$ convert magick:wizard -monochrome -colors 2 monochrome-colors-2.bmp
$ identify monochrome-colors-2.bmp
monochrome-colors-2.bmp BMP 480x640 480x640+0+0 1-bit sRGB 2c 38.5KB 0.000u 0:00.000

Wow. That actually worked:

monochrome-colors-2That was… pretty braindead behavior, but at least there was a way to do it. Oh, and btw., don't attempt to convert the non-monochrome -colors 2 images to png files with ImageMagick – the output you get is this:

colors-2-convert

Yup, that is a completely blank image…

One thought on “Monochrome images in ImageMagick?

Leave a Reply

Your email address will not be published. Required fields are marked *