1 /* 2 Implementation of a CLI command using a MagickWand API 3 4 magick -size 100x100 xc:red \ 5 \( rose: -rotate -90 \) \ 6 +append show: 7 8 9 Compile with ImageMagick-devlop installed... 10 11 gcc -lMagickWand -lMagickCore wand.c -o wand 12 13 Compile and run directly in Source Directory... 14 15 IM_PROG=api_examples/wand 16 gcc -I`pwd` -LMagickWand/.libs -LMagickCore/.libs \ 17 -lMagickWand -lMagickCore $IM_PROG.c -o $IM_PROG 18 19 sh magick.sh $IM_PROG 20 21 */ 22 #include <stdio.h> 23 #include "MagickWand/MagickWand.h" 24 25 /* Simplify the exception handling 26 * technically we should abort the program if 27 * severity >= ErrorException 28 */ 29 void ThrowWandException(MagickWand *wand) 30 { char 31 *description; 32 33 ExceptionType 34 severity; 35 36 description=MagickGetException(wand,&severity); 37 (void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); 38 description=(char *) MagickRelinquishMemory(description); 39 } 40 41 /* useful function especially after appending two wands together */ 42 #define SwapWands(a,b) { MagickWand *tmp=a; a=b; b=tmp; } 43 44 int main(int argc, char *argv[]) 45 { 46 MagickWand 47 *red, /* red image wand */ 48 *rose, /* rose image wand */ 49 *output; /* the appended output image */ 50 51 PixelWand 52 *color; 53 54 MagickBooleanType 55 status; 56 57 MagickWandGenesis(); 58 59 /* read in the red image */ 60 red = NewMagickWand(); 61 MagickSetSize(red,100,100); 62 status = MagickReadImage(red, "xc:red" ); 63 if (status == MagickFalse) 64 ThrowWandException(red); 65 /* NOTE ABOUT MagickReadImage() 66 * Unless the wand is empty set the first/last iterator to determine 67 * if the read image(s) are to be prepend/append into that wand image 68 * list. 69 * 70 * Setting a specific index always 'inserts' before that image. 71 */ 72 73 /* read in the rose image */ 74 rose = NewMagickWand(); 75 status = MagickReadImage(rose, "rose:" ); 76 if (status == MagickFalse) 77 ThrowWandException(rose); 78 79 /* rotate the rose image - one image only */ 80 color=NewPixelWand(); 81 PixelSetColor(color, "white"); 82 status = MagickRotateImage(rose,color,-90.0); 83 if (status == MagickFalse) 84 ThrowWandException(rose); 85 color = DestroyPixelWand(color); 86 87 /* append rose image into the red image wand */ 88 MagickSetLastIterator(red); 89 MagickAddImage(red,rose); 90 rose = DestroyMagickWand(rose); /* finished with 'rose' wand */ 91 /* NOTE ABOUT MagickAddImage() 92 * 93 * Always set the first/last image in the destination wand so that 94 * IM knows if you want to prepend/append the images into that wands 95 * image list. 96 * 97 * Setting a specific index always 'inserts' before that image. 98 */ 99 100 /* append all images together to create the output wand */ 101 MagickSetFirstIterator(red); 102 output = MagickAppendImages(red,MagickFalse); 103 red = DestroyMagickWand(red); /* finished with 'red' wand */ 104 /* NOTE ABOUT MagickAppendImages() 105 * 106 * It is important to either set first or reset the iterator before 107 * appending images, as only images from current image onward are 108 * appended together. 109 * 110 * Also note how a new wand is created by this operation, and that want 111 * does not inherit any settings from the previous wand (at least not at 112 * this time). 113 */ 114 115 /* Final output */ 116 status = MagickWriteImage(output,"show:"); 117 if (status == MagickFalse) 118 ThrowWandException(output); 119 120 output = DestroyMagickWand(output); 121 122 MagickWandTerminus(); 123 } 124 125 /* 126 * The above can be simplified further. 127 * 128 * Specifically you can read the 'rose' image directly into the 'red' image 129 * wand. Then process just that rose image, even though it is sharing the 130 * same wand as another image. 131 * 132 * Remember in MagickWand, simple image operators are only applied to the 133 * current image in the wand an to no other image! To apply a simple image 134 * operator (like MagickRotateImage()) to all the images in a wand you must 135 * iterate over all the images yourself. 136 */ 137 138