Compose CMYK image from layers

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
shagren

Compose CMYK image from layers

Post 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
shagren

Re: Compose CMYK image from layers

Post 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 ?
User avatar
anthony
Posts: 8883
Joined: 2004-06-01T02:27:03+00:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Compose CMYK image from layers

Post 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.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
dmi3kno
Posts: 3
Joined: 2019-07-31T19:46:33+00:00
Authentication code: 1152

Re: Compose CMYK image from layers

Post 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.
snibgo
Posts: 12159
Joined: 2010-01-24T06:01:33+00:00
Authentication code: 1151
Location: England, UK

Re: Compose CMYK image from layers

Post 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.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-03T00:14:51+00:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Compose CMYK image from layers

Post 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)
snibgo
Posts: 12159
Joined: 2010-01-24T06:01:33+00:00
Authentication code: 1151
Location: England, UK

Re: Compose CMYK image from layers

Post 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.
snibgo's IM pages: im.snibgo.com
dmi3kno
Posts: 3
Joined: 2019-07-31T19:46:33+00:00
Authentication code: 1152

Re: Compose CMYK image from layers

Post 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?
snibgo
Posts: 12159
Joined: 2010-01-24T06:01:33+00:00
Authentication code: 1151
Location: England, UK

Re: Compose CMYK image from layers

Post 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.
snibgo's IM pages: im.snibgo.com
dmi3kno
Posts: 3
Joined: 2019-07-31T19:46:33+00:00
Authentication code: 1152

Re: Compose CMYK image from layers

Post 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
Last edited by dmi3kno on 2019-08-01T18:03:45+00:00, edited 2 times in total.
snibgo
Posts: 12159
Joined: 2010-01-24T06:01:33+00:00
Authentication code: 1151
Location: England, UK

Re: Compose CMYK image from layers

Post 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.
snibgo's IM pages: im.snibgo.com
Post Reply