Naturomics
Naturomics

Reputation: 113

How to convert the imagemagick sparse-color Barycentric command line to magick++ code?

I am trying to convert a simple ImageMagick command line to Magick++/c++ code. However it didn't work as expected. The offical website lack of API example. I can not figure out the problem even I dive into the related implement code. And Google doesn't give any hint.

ImageMagick command:

convert -size 543x114 xc: -sparse-color Barycentric '0,0 red 0,%h blue' gradient.png

I want to copy its effect by following code, but the output is inconsistent.

Magick++ code:

#include <Magick++.h>

int main()
{
    int width = 543;
    int height = 114;
    Magick::Image gradImage(Magick::Geometry(width, height), Magick::Color("white"));
    // installed magick++ is built --with-quantum-depth=8
    double maxRGB = 255;

    double args[] = {
        0, 0,
        maxRGB, 0, 0,
        0, height,
        0, 0, maxRGB
    };

    gradImage.sparseColor(
        (Magick::ChannelType)((Magick::DefaultChannels & ~Magick::OpacityChannel) & ~Magick::IndexChannel),
        Magick::BarycentricColorInterpolate,
        sizeof(args) / sizeof(double),
        args
    );

    gradImage.write("gradient.png");
}

CMakelist.txt:

cmake_minimum_required(VERSION 3.16)

project(demo)
find_package(ImageMagick COMPONENTS Magick++)
include_directories(
    ${ImageMagick_INCLUDE_DIRS}
)

add_executable(
    demo
    main.cpp
)

target_link_libraries(
    demo
    ${ImageMagick_Magick++_LIBRARY}
)

generated by command: imagemagick

generated by magick++:magick++

Other Info:

Any help is appreciated!

I want the magick++ code have same effect with the command line

Upvotes: 0

Views: 80

Answers (1)

emcconville
emcconville

Reputation: 24419

You've almost got it! It might be worth peaking at the source code for GenerateCoefficients to read the expected arguments, and SparseColorOption to see how the CLI options get parsed.

  • The R, G, B values should be in a range between 0.0 & 1.0.
  • You'll need at least 3 points, as the coefficients for Barycentric are the same as Affine.
  • If you're not targeting color traits / masks, just use DefaultChannels.

Try the following...

#include <Magick++.h>

int main(int argc, char **argv)
{
  double
    width = 543.0,
    height = 114.0;
  Magick::InitializeMagick(*argv);
  Magick::Geometry rect((int)width, (int)height);
  Magick::Image gradImage(rect, Magick::Color("white"));
  Magick::ColorRGB color1("red");
  Magick::ColorRGB color2("blue");
  double args[15] = {
        0,      0, color1.red(), color1.green(), color1.blue(),
    width,      0, color1.red(), color1.green(), color1.blue(),
        0, height, color2.red(), color2.green(), color2.blue()
  };
  gradImage.sparseColor(
    Magick::DefaultChannels,
    Magick::BarycentricColorInterpolate,
    15,
    args
  );
  gradImage.write("gradient.png");
}

Sparse-Color Barycentric

Don't forget to call Magick::InitializeMagick() first thing!

Upvotes: 2

Related Questions