Rahul
Rahul

Reputation: 1123

How to combine images using MagickWand C API?

I have a two images And I want to combine them together, similar command for this is convert one.png two.png +clone -combine displaceMask.png. Below is my C Code. I'm not getting the perfect result using C.

#include <stdio.h>
#include "MagickWand/MagickWand.h"
int main(int argc, const char * argv[]) {

  MagickWand *wand1, *wand2, *wand3;

  wand1 = NewMagickWand();
  wand2 = NewMagickWand();
  wand3 = NewMagickWand();

  MagickReadImage(wand1, "one.png");
  MagickReadImage(wand2, "two.png");

  // convert one.png two.png +clone -combine displaceMask.png
  wand3 = CloneMagickWand(wand2);
  MagickAddImage(wand1, wand2);
  MagickAddImage(wand1, wand3);
  MagickCombineImages(wand1,RGBColorspace);
  MagickWriteImage(wand1,"merge.png");

  if(wand1)wand1 = DestroyMagickWand(wand1);
  if(wand2)wand2 = DestroyMagickWand(wand2);
  if(wand3)wand3 = DestroyMagickWand(wand3);
  MagickWandTerminus();

  return 0;
}

These are the images.

one.png

enter image description here two.png

enter image description here finalResultUsingCMd.png

enter image description here

merge.png (This image I'm getting using C code. But I want a above image.) enter image description here

Upvotes: 1

Views: 994

Answers (1)

emcconville
emcconville

Reputation: 24439

Updated Answer

In addition to capturing combine results, you'll need to reset the wand iterator before applying the MagickCombineImages. This is because each time you invoke MagickAddImage the internal linked list is pointing to the newly added node. (Hope I explained that clearly.)

Quoting some documents...

After using any images added to the wand using MagickAddImage() or MagickReadImage() will be prepended before any image in the wand.

Also the current image has been set to the first image (if any) in the Magick Wand. Using MagickNextImage() will then set teh current image to the second image in the list (if present).

This operation is similar to MagickResetIterator() but differs in how MagickAddImage(), MagickReadImage(), and MagickNextImage() behaves afterward.

So your example code should look like ...

#include "MagickWand/MagickWand.h"
int main(int argc, const char * argv[]) {

  MagickWand
      *wand1,
      *wand2,
      *wand3,
      *result;

  wand1 = NewMagickWand();
  wand2 = NewMagickWand();

  MagickReadImage(wand1, "one.png");
  MagickReadImage(wand2, "two.png");

  // convert one.png two.png +clone -combine displaceMask.png
  wand3 = CloneMagickWand(wand2);
  MagickAddImage(wand1, wand2);
  MagickAddImage(wand1, wand3);
  MagickSetFirstIterator(wand1);
  result = MagickCombineImages(wand1, MagickGetImageColorspace(wand1));
  MagickWriteImage(result,"merge.png");

  wand1 = DestroyMagickWand(wand1);
  wand2 = DestroyMagickWand(wand2);
  wand3 = DestroyMagickWand(wand3);
  result = DestroyMagickWand(result);
  MagickWandTerminus();

  return 0;
}

copy of merge.png

Original Answer

The MagickCombineImages method should return a pointer MagickWand * containing the result of the combine action. The behavior of this method has changed between version of IM 6 & IM 7, so it's more than possible that a bug exists, or implementation has adjusted. I'm not around IM 7 to verify at the moment, but here's a work around.

// convert one.png two.png +clone -combine displaceMask.png
wand3 = CloneMagickWand(wand2);
MagickCompositeImage(wand1, wand2, CopyGreenCompositeOp, MagickTrue, 0, 0);
MagickCompositeImage(wand1, wand3, CopyBlueCompositeOp,  MagickTrue, 0, 0);
MagickWriteImage(wand1, "merge.png");

merge.png

Upvotes: 1

Related Questions