The same ImageMagick example, using many different API's
diff --git a/api_examples/wand.c b/api_examples/wand.c new file mode 100644 index 0000000..7d4e2e6 --- /dev/null +++ b/api_examples/wand.c
@@ -0,0 +1,137 @@ +/* + Implementation of a CLI command using a MagickWand API + + magick -size 100x100 xc:red \ + \( rose: -rotate -90 \) \ + +append show: + + + Compile with ImageMagick-devlop installed... + + gcc -lMagickWand -lMagickCore wand.c -o wand + + Compile and run directly in Source Directory... + + IM_PROG=api_examples/wand + gcc -I`pwd` -LMagickWand/.libs -LMagickCore/.libs \ + -lMagickWand -lMagickCore $IM_PROG.c -o $IM_PROG + + sh magick.sh $IM_PROG + +*/ +#include <stdio.h> +#include "MagickWand/MagickWand.h" + +/* Simplify the exception handling + * technically we should abort the program if + * severity >= ErrorException + */ +void ThrowWandException(MagickWand *wand) +{ char + *description; + + ExceptionType + severity; + + description=MagickGetException(wand,&severity); + (void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); + description=(char *) MagickRelinquishMemory(description); +} + +/* useful function especially after appending two wands together */ +#define SwapWands(a,b) { MagickWand *tmp=a; a=b; b=tmp; } + +int main(int argc, char *argv[]) +{ + MagickWand + *red, /* red image wand */ + *rose, /* rose image wand */ + *output; /* the appended output image */ + + PixelWand + *color; + + MagickBooleanType + status; + + MagickWandGenesis(); + + /* read in the red image */ + red = NewMagickWand(); + MagickSetSize(red,100,100); + status = MagickReadImage(red, "xc:red" ); + if (status == MagickFalse) + ThrowWandException(red); + /* NOTE ABOUT MagickReadImage() + * Unless the wand is empty set the first/last iterator to determine + * if the read image(s) are to be prepend/append into that wand image + * list. + * + * Setting a specific index always 'inserts' before that image. + */ + + /* read in the rose image */ + rose = NewMagickWand(); + status = MagickReadImage(rose, "rose:" ); + if (status == MagickFalse) + ThrowWandException(rose); + + /* rotate the rose image - one image only */ + color=NewPixelWand(); + PixelSetColor(color, "white"); + status = MagickRotateImage(rose,color,-90.0); + if (status == MagickFalse) + ThrowWandException(rose); + color = DestroyPixelWand(color); + + /* append rose image into the red image wand */ + MagickSetLastIterator(red); + MagickAddImage(red,rose); + rose = DestroyMagickWand(rose); /* finished with 'rose' wand */ + /* NOTE ABOUT MagickAddImage() + * + * Always set the first/last image in the destination wand so that + * IM knows if you want to prepend/append the images into that wands + * image list. + * + * Setting a specific index always 'inserts' before that image. + */ + + /* append all images together to create the output wand */ + MagickSetFirstIterator(red); + output = MagickAppendImages(red,MagickFalse); + red = DestroyMagickWand(red); /* finished with 'red' wand */ + /* NOTE ABOUT MagickAppendImages() + * + * It is important to either set first or reset the iterator before + * appending images, as only images from current image onward are + * appended together. + * + * Also note how a new wand is created by this operation, and that want + * does not inherit any settings from the previous wand (at least not at + * this time). + */ + + /* Final output */ + status = MagickWriteImage(output,"show:"); + if (status == MagickFalse) + ThrowWandException(output); + + output = DestroyMagickWand(output); + + MagickWandTerminus(); +} + +/* + * The above can be simplified further. + * + * Specifically you can read the 'rose' image directly into the 'red' image + * wand. Then process just that rose image, even though it is sharing the + * same wand as another image. + * + * Remember in MagickWand, simple image operators are only applied to the + * current image in the wand an to no other image! To apply a simple image + * operator (like MagickRotateImage()) to all the images in a wand you must + * iterate over all the images yourself. + */ +