c++imagemagickmagick++image-preprocessing

Converting image magick convert command to magick++ c++ code


Converting image magick command to magick++ c++ code

I am new to Magick++. I am working on a project to dynamically make button image objects. Browsing through some help pages, I was able to create the following convert command that does what I wanted. Now I am trying migrate this to c++. Thanks in advance for any help.

    convert \( -size 110x30 xc:none -fill '#bdbdbd' -draw 'roundrectangle 0,0 109,29 5,5' \) \
            \( -clone 0 -alpha extract \) \
            \( -clone 0 -bordercolor none -border 9 -channel rgba -blur 9x65000 -shave 9x9 \) \
            -delete 0 +swap -alpha off -compose copy_opacity -composite -auto-level -alpha off +level-colors '#0D5A84','#19AAF9' -alpha on tmp-1.png

    double width = 110.0;
    double height = 30.0;
    Magick::Image button(Magick::Geometry(width, height), "none");
    button.fillColor("#bdbdbd"); // Fill color
    button.draw(Magick::DrawableRoundRectangle(0.0/*XCenter*/, 0.0/*YCenter*/,
            width-1.0, height-1.0, 5.0/*cornerWidth*/, 5.0/*cornerHeight*/));
    // \( -clone 0 -alpha extract \)
    Magick::Image layer1(button);
    layer1.alpha(); // how to set alpha extract and how this layer is used?

    //\( -clone 0 -bordercolor none -border 9 -channel rgba -blur 9x65000 -shave 9x9 \)
    Magick::Image layer2(button);
    layer2.bordercolor("none");
    layer2.border(Magick::border()); //parameter is of type Geometry not double
    layer2.channel(RGBChannels); //rgba
    layer2.blur(9, 65000);
    layer2.shave(Magick::Geometry(9, 9));
    //how to -delete 0
    //how to +swap
    button.alpha(false);
    button.composite(layer2, "+0+0", MagickCore::CompositeOperator::OverCompositeOp); //-compose copy_opacity -composite
    button.alpha(false);
    //how to level colors
    button.alpha(true);
    button.write("button.png");

Solution

  • Happy to help you along, but in the future, try to keep minimal reproducible question. A dump of all problems is hard to answer.

    // \( -clone 0 -alpha extract \)
    Magick::Image layer1(button);
    layer1.alpha(); // how to set alpha extract and how this layer is used?
    

    Use Magick::Image.alphaChannel(Magick::ExtractAlphaChannel) instead of Magick::Image.alpha().

    layer2.border(Magick::border()); //parameter is of type Geometry not double
    

    The CLI behavior knows that -border 9 really means -border 9x9, so the geometry should reflect that.

    layer2.border(Magick::Geometry(9, 9));
    
    //how to -delete 0
    //how to +swap
    

    You can ignore these operators as you are working in an OOP language --- that is to say ---- you're already doing it with instance variables. Just pay attention to the order of operations.

    //how to level colors
    

    Ah! Now this is a tricky one. With Magick++ you would call Magick::Image.levelColors(), but the CLI command is calling +level-colors -- which is the inverse method called levelize, but Magick::Image.levelizeColors() doesn't exist in Magick++ (yet). You'll have to find an alternative solution.

    The method Magick::Image.levelizeChannel() does exists, so some quick maths, and you can translate the color-channel-parts into white & black points.

    /*
       +level-colors '#0D____','#19____'
       blackpoint = 3276.75 = 0x0D / 255.0 * QuantumRange
       whitepoint = 5898.15 = 0x19 / 255.0 * QuantumRange
       Where QuantumRange is usually 65535
    */
    button.levelizeChannel(Magick::RedChannel, 3276.75, 5898.15);
    /*
       +level-colors '#__5A__','#__AA__'
       blackpoint = 22937.25 = 0x5A / 255.0 * QuantumRange
       whitepoint = 43253.1 = 0xAA / 255.0 * QuantumRange
       Where QuantumRange is usually 65535
    */
    button.levelizeChannel(Magick::GreenChannel, 22937.25, 43253.1);
    /*
       +level-colors '#____84','#____F9'
       blackpoint = 33422.85 = 0x84 / 255.0 * QuantumRange
       whitepoint = 63568.95 = 0xF9 / 255.0 * QuantumRange
       Where QuantumRange is usually 65535
    */
    button.levelizeChannel(Magick::BlueChannel, 33422.85, 63568.95);
    

    Update

    Looks like I overlooked the invert paramater for the Magick::Image.levelColors() method. Disregard the workaround levelizeChannel method above, and use the following....

    // +level-colors '#0D5A84','#19AAF9'
    button.levelColors(Magick::Color("#0D5A84"), Magick::Color("#19AAF9"), true);