Page 1 of 1

Wands blend to implement colorize don't match with CLI

Posted: 2014-08-25T07:57:45-07:00
by tommi_v
Hi. I tried to convert a pretty well-known snippet for image color-tone from CLI version to Wand:

Code: Select all

convert \
        in.jpg \
        \( -clone 0 -fill '#222b6d' -colorize 100% \) \
        \( -clone 0 -colorspace gray \) \
        -compose blend -define compose:args=100,0 -composite \
       out.jpg
I assume this codes does this:
1) Read input to layer, let's call it layer[0] (the bottom one)
2) Clone layer[0] to colorized version and put layer[1] (the middle one)
3) Clone layer[0] to grayscale and put it to layer[2] (the top one)
4) Set some magic (have no clue what does this two args 100,0 in compose means)
5) Set blending mode to... blend
6) Finally blend layers and write output

It works well from CLI, but I stucked on 4 or 5 step in c code.
I split task to subtasks. This CLI code:

Code: Select all

convert \
        in.jpg \
        \( -clone 0 -fill '#222b6d' -colorize 100% \) \
        -compose blend -composite \
       out.jpg
Transforms to

Code: Select all

	MagickWand* colorlayer = CloneMagickWand(wand);
	PixelWand* tone = NewPixelWand();
	PixelSetColor(tone, tonecolor);
	PixelWand* opacity = NewPixelWand();
	PixelSetColor(opacity, "rgb(100%,100%,100%)");
	MagickColorizeImage(colorlayer, tone, opacity);
	DestroyPixelWand(tone);
	DestroyPixelWand(opacity);
 
       MagickCompositeImage(wand, colorlayer, BlendCompositeOp, 0, 0);

       DestroyMagickWand(colorlayer);
In this step, result from CLI and Wand are the same.
So far, so good. Now I added command with gray layer[2], but without compose:args

Code: Select all

convert \
        in.jpg \
        \( -clone 0 -fill '#222b6d' -colorize 100% \) \
        \( -clone 0 -colorspace gray \) \
        -compose blend -composite \
       out.jpg

Code: Select all

        MagickWand* colorlayer = CloneMagickWand(wand);
	PixelWand* tone = NewPixelWand();
	PixelSetColor(tone, tonecolor);
	PixelWand* opacity = NewPixelWand();
	PixelSetColor(opacity, "rgb(100%,100%,100%)");
	MagickColorizeImage(colorlayer, tone, opacity);
	DestroyPixelWand(tone);
	DestroyPixelWand(opacity);

	MagickWand* graylayer = CloneMagickWand(wand);
	MagickSetImageColorspace(graylayer, GRAYColorspace);

	MagickCompositeImage(wand, colorlayer, BlendCompositeOp, 0, 0);
	MagickCompositeImage(wand, graylayer, BlendCompositeOp, 0, 0);

	DestroyMagickWand(colorlayer);
	DestroyMagickWand(graylayer);
But this is already makes things failed: CLI version is almost the same as input, while Wand result is "washed" but overexposed (too bright). I assume that main problem is with compose:args, especially with different defaults for CLI and Wand. But I can't find out how to make it the same, or, even better, to make my Wand program to yield same as CLI result. I tried naive

Code: Select all

MagickSetImageArtifact(wand, "compose:args", "100,0");
which doesn't work – nothing really changed. I tried to change wand in this call to gray layer or colored layer, I tried even to set same args to all three wands. I tried to swap arguments order or to set extereme values, like 10000. Some times this changes picture dramatically, but I still can't get desired result.

My ImageMagick version is

Code: Select all

convert --version
Version: ImageMagick 6.8.9-6 Q16 x86_64 2014-07-29 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC
Delegates: bzlib jng jpeg png xml zlib
I run it on MacOS Yosemite, compiler is clang.