This project has moved and is read-only. For the latest updates, please go here.

Does ImageMagick read/convert TrueColor TIF as Grayscale?

Apr 25, 2014 at 7:17 AM
Hi, I have an uncompressed 24bit Tif image and I want it to stay TrueColor however:
using (MagickImage image = new MagickImage(@"F:\wireframe.tif"))
{    
    ColorType ct = image.ColorType; //ColorType.Grayscale
    ColorSpace cs = image.ColorSpace; //ColorSpace.GRAY
             
    image.Write(@"F:\same_wireframe.tif");
}
The converted image is no longer true color but grayscale.
wireframe.tif size is: 480 678 bytes (400x400x3)
same_wireframe.tif size is: 160 470 bytes (400x400x1)
The Command Line version of Image Magick behaves the same way so maybe I post this in the wrong place?

It seems that I can’t attach the images in this discussion but the same thing happens with every 24bit image storing grayscale color information.
For example: I created a new RGB image in Gimp with white background than I painted to it with black paintbrush and exported it as uncompressed Tif.

Image Magick .Net
Type: Nuget Id: Magick.NET-Q8-x64 Version: 6.8.8.1001

Image Magick Command Line
7.0.0-0 Q16 x64 2014-01-19
Apr 25, 2014 at 8:01 AM
Edited Apr 25, 2014 at 8:02 AM
Magick.NET does not use ImageMagick 7 yet so there could be some differences between Magick.NET and the command line. Feel free to post your questions that are related to ImageMagick here. I am also involved in that project. Can you post a link to your tif image so I can run some tests with it?
Apr 25, 2014 at 8:38 AM
Can I send it to you as an email attachment?
Apr 25, 2014 at 9:43 AM
Thank for your e-mail. I will look into it.
Apr 26, 2014 at 6:24 PM
It turns out that this change in colorspace is by design. ImageMagick detects the image can be changed to Grayscale. This will save space when the image is saved. If you want to get the original colorspace you should use the following code:
image.GetAttribute("tiff:photometric");
Apr 28, 2014 at 11:39 AM
Yeah, it ran through my mind but I forgot to ask: Is it a bug or feature?
Furthermore, I found a similar thread in the ImageMagick community: PNG conversion forcing grayscale
I should have read that before, sorry.
It turns out that this change in colorspace is by design
I think the ColorType which is changing not the ColorSpace.
The ColorSpace.GRAY and ColorSpace.sRGB are the same things.
string colorSpace = image.GetAttribute("tiff:photometric"); //colorSpace = “RGB”
I’m not an expert but I think actually there is no GRAY or RGB ColorSpace: Wiki:Colorspace

The ColorType property which is tells us how the numbers are stored in the container/object (3 channel, 1 channel, indexed, etc.).
The ColorSpace tells us what the numbers mean, right?

Anyway, thank you for your time.
Now that I know this is a feature I can push it to the right direction.:)
Thanks!
Apr 28, 2014 at 12:34 PM
You are correct the ColorType is changing but that is causing the ColorSpace to change also. ImageMagick uses the GRAY colorspace internally to make it a 'one channel' image. And there is actually an RGB colorspace.

You should do something like this to maintain TrueColor:
using (MagickImage image = new MagickImage(@"F:\wireframe.tif"))
{    
  if (image.ColorType == ColorType.Grayscale && image.GetAttribute("tiff:photometric") == "RGB")
  {
    image.ColorType = ColorType.TrueColor;
    image.ColorSpace = ColorSpace.sRGB;
  }             
  image.Write(@"F:\same_wireframe.tif");
}

The behavior is a feature and not a bug.
Apr 28, 2014 at 3:58 PM
Edited Apr 28, 2014 at 5:40 PM
I split the discussion into two viewpoints to prevent the misunderstandings:

Viewpoint 1 - The developer perspective

  • I understand and I’m aware the internal concept of the changing properties (ColorSpace, ColorType).
  • Does the code example work for you?”
Yes, I’m already doing that from the beginning and it works! Thanks!
  • The behavior is a feature and not a bug.
Yes, I understand that too, I wrote:
Now that I know this is a feature…
Is it a good feature? If the user knows what’s going on, than yes, it can be very helpful thing. If he/she isn’t aware that the ImageMagick objects do not necessarily represent the real things on the file system (or it is not obvious for the first time), in some situations, that can be troublesome. But as I had learnt this, everyone can.

Viewpoint 2 - The theoretical perspective or as science guys talk ( not me :) )

  • The term “changing from one ColorSpace to another” is a bit confusing because Colorspace.GRAY and Colorspace.sRGB means the same thing or is there a GRAY ColorSpace?
  • I’m not an image or color expert and I happily learn every day something new. For example in discussions like this.:)
    The wiki page about the RGB ColorSpace really confuses me.
The first statement from the ColorSpace page:
For example, although several specific color spaces are based on the RGB model, there is no such thing as the RGB color space.
The second statement from the RGB ColorSpace page:
The complete specification of an RGB color space also requires a white point chromaticity and a gamma correction curve.
So this is not a complete specification then how can I use it?

The third statement from the RGB ColorSpace page:
The most commonly used RGB color spaces are sRGB and Adobe RGB
The fourth statement from the ColorSpace page:
For example, Adobe RGB and sRGB are two different absolute color spaces, both based on the RGB model.
These are conflicting statements, aren’t they?
Apr 28, 2014 at 8:17 PM
Edited Apr 29, 2014 at 11:52 AM
Viewpoint 1 - The developer perspective

Your comments made me dig into the code and figure out what is happening. It turns out that requesting the ColorType changes the ColorType and ColorSpace. I have modified ImageMagick and moved this to a separate method. This method will be called DetermineColorType and available in the next version of Magick.NET. This means that image.ColorType will return the original ColorType instead of the automatically detected ColorType. But this will still result in an output image with a gray ColorType. You can prevent this by explicitly telling ImageMagick to preserve the ColorType:
using (MagickImage image = new MagickImage(@"F:\wireframe.tif"))
{
  image.PreserveColorType();
  /*
    This will internally do the following statement that sets an internal option to explicitly use this ColorType.
    image.ColorType = image.ColorType;
  */
  image.Write(@"F:\same_wireframe.tif");
}
Viewpoint 2 - The theoretical perspective or as science guys talk ( also not me :) )

I am also not a color expert so my explanation may sound confusing. I am also still learning. If you want some more information on how ImageMagick interprets color spaces you should visit the following page: http://www.imagemagick.org/Usage/color_basics. Anthony can explain it much better then me.
Apr 30, 2014 at 9:13 AM
Edited Apr 30, 2014 at 10:33 AM
“Your comments made me dig into the code and figure out what is happening”
Yeah, I didn’t want to push this topic because it would be nice from me to read the source code and give you some C code examples. But the fact is I’m not a real programmer and I don’t understand it.

But in theory, I think, ImageMagick should behave just the opposite way:
C:\> magick bigFatSadImage.tif -tryReduceTheNumberOfChannels smallHealthyHappyImage.tif
In other way, if the users want to create a single black pixel on the center of a big white background and store this as a 64-bit transparent HDR image (and load into ImageMagick without the need to set any property), give them the tools to do it (we have the rights to be stupid!:) ).Of course this can be used really for testing purposes. Then if they want to reduce the size of their images:

-tryReduceTheNumberOfChannels
  • Check if the 64-bit image contains unnecessary channels and try to remove all of it and so on…
-tryPackPixelBits (maybe similar function already exists)
  • Check if the 16-bit channels contain such information that can be represented as 8-bit without loss of information
  • Check if the 8-bit channels can be represented as indexed
But this is just theory and that’s easy. The implementation is much harder.

About ColorSpace:
“If you want some more information on how ImageMagick interprets color spaces you should visit the following page:”
Yeah, I read that page before. Do I understand it? Well, that’s a different question.:)

I think the following words have many different meanings depending on where I read them and who uses them: ColorModel, ColorSpace, sRGB, linear RGB, RGB ColorSpace, RGB ColorSpaces.

I tried to translate them for myself, I only tried it :)

RGB ColorSpaces : ColorSpaces based on the RGB ColorModel
RGB ColorSpace 1: linear RGB (mostly converted but unprocessed camera raw images are in this form, I think ImageMagick uses this term too)
RGB ColorSpace 2: RGB ColorModel (often found on the wiki pages)
sRGB : ColorSpace based on the RGB ColorModel (most of the images and monitors(or at least they claim that) use this colorSpace)

If you want you can correct this.
May 1, 2014 at 8:00 PM
I agree with you that it might be better to add it as an option but that is not such an easy action to do. And it would also require the users that now expect this behavior to change their commands on the command line. The Magick++ (C++ code of Imagemagick) code was a bug because asking the ColorType changed the ColorType. This change in ColorType should only by done by the coder that writes the tiff image. Each format has their own coder and own code to decide what to do with the ColorType. The person who wrote the tiff coder decided that it would be best to make the image as small as possible and use Gray when possible. If we added an option for this we would have to change this in all our 120+ coders :).

I also do not understand the color spaces completely. It seems there are a lot more RGB color spaces then 3 you listed (http://en.wikipedia.org/wiki/RGB_color_space#Specifications). I have no idea which one ImageMagick uses for ColorSpace.RGB. We did make a switch a while back to fix the sRGB colorspace: http://www.imagemagick.org/script/color-management.php.
May 2, 2014 at 3:08 PM
".. we would have to change this in all our 120+ coders"
I agree with that, it would be a nightmare.
“And it would also require the users that now expect this behavior to change their commands on the command line.”
I agree with that too.

I have to read more about ColorSpaces because my knowledge is not good enough to make clear statements about this complicated topic.