139 lines
4.1 KiB
C
139 lines
4.1 KiB
C
/*
|
|
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 from 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 new
|
|
* wand 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, though that is not what "magick"
|
|
* command would do which we are simulating.
|
|
*
|
|
* Specifically you can read the 'rose' image directly on the end of of
|
|
* '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.
|
|
*/
|
|
|