Page 1 of 1

EPS MagickTransformImageColorspace() colour issue

Posted: 2013-07-02T04:21:44-07:00
by sacha
My question relates to EPS colorspace conversions, but ultimately it's really about how to change the format of an image in memory.

I'm using IM 6.7.5-4 (with later versions we have issues with dark JPEGs which we've not yet got to the bottom of).

I have a CMYK EPS file which I convert to RGB JPEG; however this results in colour issues - it's a black and white photo that ends up with a blue tint. I've narrowed this down to being caused by MagickTransformImageColorspace() when converting the image to RGB. There is some discussion here about this being down to Ghostscript's colour conversion:

http://www.ghostscript.com/pipermail/bu ... 02323.html

However the mentioned hacks to delegates.xml haven't worked for me (besides which, we prefer to rely on a stock IM distribution as far as possible). I'm using Ghostscript 9.05.

I don't have rights clearance to make the image available, but here is the identify -verbose output if relevant:

http://pastebin.com/JRAA1Pu6


The following code (using an in-house scripting language) produces the incorrect image:

Code: Select all

defconst MAGICK_RGBColorspace =  1

def main () {
    local infile = info("argv 1")
    local outfile = info("argv 2")
    local w = NewMagickWand()
    MagickReadImage(w, infile)
    MagickTransformImageColorspace(w, MAGICK_RGBColorspace)
    MagickWriteImage(w, outfile)
}
In an attempt to avoid Ghostscript's colour conversion (if that is indeed the problem), I tried saving to another format first and then doing the colour conversion from that:

Code: Select all

defconst MAGICK_RGBColorspace =  1

def main () {
    local infile = info("argv 1")
    local outfile = info("argv 2")
    local w = NewMagickWand()
    MagickReadImage(w, infile)
    MagickWriteImage(w, outfile+".png")
    MagickReadImage(w, outfile+".png")
    MagickTransformImageColorspace(w, MAGICK_RGBColorspace)
    MagickWriteImage(w, outfile)
}
This does indeed yield a much better image, so my question is, can I do this without writing the intermediate file to disk? (I suppose what I want to do is to force IM to read the image into memory in whatever its native format is, so that it no longer delegates to Ghostscript.)

Re: EPS MagickTransformImageColorspace() colour issues

Posted: 2013-07-02T05:30:22-07:00
by magick
Let Ghostscript transform the colorspace instead of ImageMagick. Use MagickSetColorspace() before your read, remove MagickTransformImageColorspace(). If that fails, you'll want to use color profiles to convert the CMYK image to sRGB.

Re: EPS MagickTransformImageColorspace() colour issues

Posted: 2013-07-02T05:33:32-07:00
by sacha
Thanks, that appears to have done the trick. The following code now produces a much better image:

Code: Select all

defconst MAGICK_RGBColorspace =  1

    def main () {
        local infile = info("argv 1")
        local outfile = info("argv 2")
        local w = NewMagickWand()
        MagickSetImageColorspace(w, MAGICK_RGBColorspace)
        MagickReadImage(w, infile)
        MagickWriteImage(w, outfile)
    }

Re: EPS MagickTransformImageColorspace() colour issue

Posted: 2013-07-02T05:48:33-07:00
by sacha
Ah no I was mistaken; it's left me with a CMYK JPEG which looks correct but isn't what I'm after.

Re: EPS MagickTransformImageColorspace() colour issue

Posted: 2013-07-02T06:06:46-07:00
by magick
Make that MagickSetColorspace().

Re: EPS MagickTransformImageColorspace() colour issue

Posted: 2013-07-02T06:51:34-07:00
by snibgo
sacha wrote:I'm using IM 6.7.5-4 (with later versions we have issues with dark JPEGs which we've not yet got to the bottom of).
Many versions after 6.7.9 to 6.8.4 assumed monochrome images were linear RGB, rather than non-linear sRGB assumed for colour images. This often created images that were darker then expected. From 6.8.5 onwards, it treated monochrome and colour alike, assuming sRGB. This is (in my view) a far better arrangement.

Re: EPS MagickTransformImageColorspace() colour issue

Posted: 2013-09-13T07:58:03-07:00
by sacha
Sadly MagickSetColorspace() doesn't appear to have any effect, at least not with the versions of ImageMagick I've been working with (6.7.7-7 is the one we're currently working with). No matter what I set the colourspace to, after reading the image with MagickReadImage() I seem to have a CMYK image. (If I write it to JPEG immediately, I end up with a CMYK JPEG.) MagickGetColorspace() reports whatever I set the colourspace to, but MagickGetImageColorspace() always reports CMYK.

These are appear to be the ghostscript flags to do the CMYK to RGB conversion:

Code: Select all

-dColorConversionStrategy=/sRGB -dProcessColorModel=/DeviceRGB -dUseCIEColor=true
If I hack this into the ps:cmyk entry in delegates.xml, when I read the image with MagickReadImage() I then get what appears to be an RGB image, and end up with what I want. Of course, I don't want to do this in delegates.xml (since I don't necessarily always want to convert CMYK EPS files to RGB), which is why I think you were suggesting MagickSetColorspace() which could alter the behaviour of ghostscript dynamically. (Reading the PS coder for 6.7.7-7, I don't see anything that looks like it would be doing this though.)

So for the moment I think I'll need to spot CMYK EPS files and invoke ghostscript myself to convert it to an intermediate format; perhaps once we catch up with later versions of ImageMagick the problem will go away.