c++imagemagickimage-manipulationmagick++

How to write these `convert` commands in Magick++?


I've decided on using Magick++ for my application. I know which convert commands I want to use but I don't know how to translate them into Magick++ code.

My application should quantize the colors in a imported image using a fixed hardcoded palette, with optional dithering (F-D, Riemersma, Bayer, Halftone, Random). It then passes the output to some later code.

Here are the commands that give me the results I want. Each one is individual, which one "gets run" depends on user set flags.
Also, palette.png will be a Image object generated on run and is not actually read from file.
Also, again, out.png will not be exported to file and will be instead be another Image object passed onto later code.

convert in.png -dither FloydSteinberg -remap palette.png out.png
convert in.png -dither Riemersma -remap palette.png out.png

convert in.png -ordered-dither o2x2,2 -remap palette.png out.png
convert in.png -ordered-dither o2x2,3 -remap palette.png out.png
convert in.png -ordered-dither o2x2,4 -remap palette.png out.png
# etc.

convert in.png -ordered-dither o3x3,2 -remap palette.png out.png
# etc.

convert in.png -ordered-dither o4x4,2 -remap palette.png out.png
# etc.

convert in.png -ordered-dither o8x8,2 -remap palette.png out.png
# etc.

# etc. through all ordered dithers

convert in.png -random-threshold 0x100% -remap palette.png out.png
convert in.png -random-threshold 10x90% -remap palette.png out.png
convert in.png -random-threshold 25x75% -remap palette.png out.png
convert in.png -random-threshold 30x80% -remap palette.png out.png

Solution

  • For -dither operator, use Magick::Image.quantizeDitherMethod() method.

    Magick::Image img("in.png");
    img.quantizeDitherMethod(Magick::FloydSteinbergDitherMethod);   
    

    For -remap operator, use Magick::Image.map() method.

    Magick::Image img("in.png");
    // ...
    Magick::Image remap("palette.png");
    img.map(remap, true);
    

    For -ordered-dither operator, use Magick::Image.orderedDither() method.

    Magick::Image img("in.png");
    // ...
    img.orderedDither("o3x3,2"); 
    

    For -random-threshold operator, use Magick::Image.randomThreshold() method.

    Magick::Image img("in.png");
    // ...
    img.randomThreshold(0.3 * QuantumRange, 0.8 * QuantumRange);  
    

    Checkout Image.h header file, and other Magick++'s source code files for reference. I believe the documentation / examples are slightly out of date, but the developer comments are clear.