Page 1 of 1

Compose CMYK image from layers

Posted: 2007-12-19T10:46:24-07:00
by shagren
I want compose image from one-four layers(Cyan, Magenta, Yellow, Black)
I try many variants, but always in result image Black layer is 1 bit.

Next code correct copy Cyan, Magenta, Yellow layers but not Black. Why?

Code: Select all

convert \
    -colorspace CMYK \
    -size 595x842 \
    -compose Copy-Magenta  out.Magenta.tif\
    -composite \
    -compose Copy-Cyan  out.Cyan.tif\
    -composite \
    -compose Copy-Black out.Black.tif \
    -composite \
    -compose Copy-Yellow out.Yellow.tif\
    -composite \
    result.jpg

Re: Compose CMYK image from layers

Posted: 2007-12-19T11:35:27-07:00
by shagren
I find information and workaround in documentation :)
http://www.imagemagick.org/Usage/bugs/testing/
CopyBlack can not handle a RGB greyscale channel image


Maybe is good to add this link on page http://www.imagemagick.org/Usage/channe ... bine_other ?

Re: Compose CMYK image from layers

Posted: 2007-12-21T00:23:17-07:00
by anthony
It was not supposed to take this long to get a solution. I was hoping to arrange it so that CopyBlack till act in a similar way that CopyOpacity does when the source image did not contain the channel that was requested to be copied, and that is copy the images grayscale intensity instead.

That is a grayscale channel image for a Black channel, does not contain a black channel itself, so CopyBlack should copy the grayscale values instead. This is actually what CopyOpacity does (ASIDE: though CopyOpacity also negates that channel as a alpha channel)

At the moment this is NOT what is being done, but what should be done.

Re: Compose CMYK image from layers

Posted: 2019-07-31T14:17:12-07:00
by dmi3kno
In many places around this site, including http://www.imagemagick.org/Usage/bugs/testing/ and here https://www.imagemagick.org/Usage/color ... bine_other the explanation is given as:
The last example will not work for 'CMYK' images, as the 'Black' channel image does not actually contain a black channel! As such "-compose CopyBlack" will fail to find valid data to copy.
But reality is that "Copy-Black" seems to break picture even if valid copy of the black channel is provided:

Code: Select all

convert rose_cmyk.tif rose_cmyk.tif -compose Copy-Black -composite rose_reblacked.tif
Given that the source and the destination is identical, and given that it is critical for "Black" channel to not only have greyscale representation of the Black channel, but also the actual Black channel, this should just overwrite it with the same data and not amend the picture. Instead, this is what we get
Image

There's something fundamentally wrong with Copy-Black operator and it is independent of presence of Black channel in the source or destination image.

Re: Compose CMYK image from layers

Posted: 2019-07-31T15:17:56-07:00
by snibgo
It seems to be a bug in composite.c:

Code: Select all

          case CopyBlackCompositeOp:
          {
            if (channel == BlackPixelChannel)
              pixel=(MagickRealType) (QuantumRange-
                GetPixelBlack(source_image,p));
            break;
          }
          case CopyBlueCompositeOp:
          case CopyYellowCompositeOp:
          {
            if (channel == BluePixelChannel)
              pixel=(MagickRealType) GetPixelBlue(source_image,p);
            break;
          }
          case CopyGreenCompositeOp:
          case CopyMagentaCompositeOp:
          {
            if (channel == GreenPixelChannel)
              pixel=(MagickRealType) GetPixelGreen(source_image,p);
            break;
          }
The "copy" composites simply copy the value, but CopyBlack subtracts the value from QuantumRange. I see no good reason for this, and suspect a bug.

Re: Compose CMYK image from layers

Posted: 2019-07-31T15:51:59-07:00
by fmw42
Could it be that black in CMYK is inverted and ImageMagick is taking that into account when -copy black?

convert xc:black -colorspace cmyk txt:
# ImageMagick pixel enumeration: 1,1,65535,cmyk
0,0: (0,0,0,65535) #000000000000FFFF cmyk(0,0,0,255)

Re: Compose CMYK image from layers

Posted: 2019-07-31T17:02:50-07:00
by snibgo
It is copying the black channel from one CMYK image to another CMYK image. So there should be no inversion. Just as there is no inversion when copying the yellow or magenta channels.

In the command shown by dmi3kno, when the two equal inputs are CMYK, the output CMYK should be unchanged. But it has a negated black channel.

Re: Compose CMYK image from layers

Posted: 2019-08-01T07:44:12-07:00
by dmi3kno
So I am happy to report that removing that QuantumRange fixes the issue with negated Black channel. Just recompiled ImageMagick on my Ubuntu machine and the issue is gone. The only thing you need to ensure is that the image that you are "copyingBlack from" does in fact contain Black channel i.e. if you have the B/W image that you made using -separate you need to first convert it to CMYK before applying CopyBlack operator to it.

Yay! We fixed the issue. Thank you @snibgo.

Not sure we broke something in the process, but this was super fast.

Code: Select all

(QuantumRange- GetPixelBlack(source_image,p))
Perhaps this ^ came from definition of CMYK colorspace here https://imagemagick.org/script/command- ... colorspace, but it does not match the formula there either. Another thought: it is a little counterintuitive that user needs to convert Grayscale image of the K channel to CMYK in order for CopyBlack to work. User believes grayscale values become K channel automatically, as the case is with CopyOpacity. I wonder if it is possible to "convert - colorspace CMYK" that image on the fly before applying the CopyBlack operation?

Re: Compose CMYK image from layers

Posted: 2019-08-01T08:24:59-07:00
by snibgo
I have reported this as a bug: https://www.imagemagick.org/discourse-s ... =3&t=36465
dmi3kno wrote:The only thing you need to ensure is that the image that you are "copyingBlack from" does in fact contain Black channel ...
Yes. The test case should be when both inputs are CMYK. If this isn't true, we can expect weird behaviour. The black channel, K of CMYK, is the amount of (subtractive) black ink, thus 100% is full black. In a grayscale image, colours are additive, so 0 is full black.

Re: Compose CMYK image from layers

Posted: 2019-08-01T10:13:09-07:00
by dmi3kno
The black channel, K of CMYK, is the amount of (subtractive) black ink, thus 100% is full black. In a grayscale image, colours are additive, so 0 is full black.
Oh so this was the idea behind QuantumRange-GetPixelBlack(source_image,p)! Ok. Why was it failing for grayscale, then?

Sorry I edited my post. Realized I said something completely stupid

Re: Compose CMYK image from layers

Posted: 2019-08-01T10:59:26-07:00
by snibgo
By magick, of course.

For a better answer, see the source code in composite.c and follow the trail for GetPixelGreen() etc. Then (if in v7) you will see access is via the image channel_map structure.