| /* |
| 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. |
| */ |
| |