Page 1 of 1

Cannot append color image to grayscale image - IM 6.9.0-2

Posted: 2014-12-29T02:00:22-07:00
by jjv
Hi everyone,

Since the upgrade to 6.8, which included some major changes in color management, the convert -append command has been broken when dealing with mixed grayscale and color images. Consider the following command:

Code: Select all

$ convert bw.jpg color.jpg -append both.jpg
(The images I'm using are available here and here. They were exported from Lightroom and then scaled down with convert -resize)

The expected and correct result should be that both.jpg is a color image, of which the top half shows the contents of bw.jpg and the bottom half the contents of color.jpg. However, the actual and incorrect result is that both.jpg is a grayscale image. This can be observed by opening it in any image viewer or with the identify command:

Code: Select all

$ identify -verbose both.jpg | grep Colorspace
Colorspace: Gray
I have tried to explicitly specify the colorspaces and image types, but to no avail:

Code: Select all

$ convert -colorspace sRGB -type truecolor bw.jpg -colorspace sRGB -type truecolor color.jpg -append -colorspace sRGB -type truecolor both.jpg
This behavior only occurs when the grayscale image is the first to be appended. The following code produces the correct result:

Code: Select all

$ convert color.jpg bw.jpg -append both.jpg
It seems that ImageMagick decides on the output colorspace depending on the colorspace of its first argument, and that this behavior cannot be overruled. This bug affects me greatly, since I have a photographer client whose online portfolio suddenly contains grayscale preview icons. If there is any workaround that successfully combines bw.jpg and color.jpg, please let me know!

Re: Cannot append color image to grayscale image - IM 6.9.0-2

Posted: 2014-12-29T03:10:03-07:00
by snibgo
Bug confirmed in v6.9.0-0, on Windows 8.1.

v6.8.9-0 didn't have this bug.

Re: Cannot append color image to grayscale image - IM 6.9.0-2

Posted: 2014-12-29T03:19:34-07:00
by snibgo
A workaround is to start the image list with a dummy colour image, then trim it off, eg:

Code: Select all

convert xc:red bw.jpg color.jpg -append -crop +0+1 +repage both.jpg
Incidentally, I wouldn't append JPG images together with IM as it will decompress then recompress, potentially losing quality. I use JPG only as a final output format, never as input to further processing.

Re: Cannot append color image to grayscale image - IM 6.9.0-2

Posted: 2014-12-29T06:12:06-07:00
by jjv
snibgo wrote:A workaround is to start the image list with a dummy colour image, then trim it off, eg:

Code: Select all

convert xc:red bw.jpg color.jpg -append -crop +0+1 +repage both.jpg
Thanks for the quick response and functional workaround! I'm editing the photographer's website scripts right now.
snibgo wrote: Incidentally, I wouldn't append JPG images together with IM as it will decompress then recompress, potentially losing quality. I use JPG only as a final output format, never as input to further processing.
Yes, I know. In my case I'm also scaling the output image down so the quality degradation is not visible. But I checked anyway to see if the bug persists when using PNG and other image types, and it does. This seems to indicate that the bug is somewhere in the AppendImages function in magick/image.c, rather than in the encoding/decoding stage.

Re: Cannot append color image to grayscale image - IM 6.9.0-2

Posted: 2014-12-29T06:55:51-07:00
by jjv
I did some digging and found the following:

magick/image.c, line 492:

Code: Select all

  append_image=CloneImage(images,width,height,MagickTrue,exception);
Here the append_image is constructed by cloning the first image of the array of images to be appended. The CloneImage function also clones colorspace, meaning that the output colorspace will be equal to the colorspace of the first image to be appended.

magick/image.c, lines 508-524:

Code: Select all

  for (n=0; n < (MagickOffsetType) number_images; n++)
  {
    CacheView
      *image_view;

    Image
      *image;

    MagickBooleanType
      proceed;

    image=CloneImage(next,0,0,MagickTrue,exception);
    if (image == (Image *) NULL)
      break;
    status=TransformImageColorspace(image,append_image->colorspace);
    if (status == MagickFalse)
      break;
Here the function TransformImageColorspace is called with two arguments: 1. the current image and 2. the colorspace of the append_image (which is equal to the colorspace of the first image as we saw above.).

So the bug seems two-fold: First, the output image has the same colorspace as the first input image, which is wrong. Second, the colorspace of each image get transformed to the colorspace of the output image, which is not necessarily wrong but in this case it is, because the colorspace of the output image was wrong to begin with.

I don't know how previous versions of ImageMagick handled colorspaces, but the example code in my original question used to work as intended. I noticed a big rewrite of the AppendImages function between versions 6.6 and 6.7. My guess is that the original code simply assumed the colorspace to be linear RGB.

Re: Cannot append color image to grayscale image - IM 6.9.0-2

Posted: 2014-12-29T07:11:04-07:00
by snibgo
[Post deleted. I was confusing my versions.]