blob: d71059bb8da28f9c4690998c2ed0a991ea7a2861 [file] [log] [blame]
anthony25247ae2013-03-18 05:05:40 +00001/*
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
Anthony Thyssen5b7198d2016-12-20 11:05:09 +100013 Compile and run directly from Source Directory...
anthony25247ae2013-03-18 05:05:40 +000014
15 IM_PROG=api_examples/wand
16 gcc -I`pwd` -LMagickWand/.libs -LMagickCore/.libs \
17 -lMagickWand -lMagickCore $IM_PROG.c -o $IM_PROG
18
Anthony Thyssen5b7198d2016-12-20 11:05:09 +100019 sh ./magick.sh $IM_PROG
anthony25247ae2013-03-18 05:05:40 +000020
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 */
29void 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
44int 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 *
Anthony Thyssen5b7198d2016-12-20 11:05:09 +1000106 * It is important to either 'set first' or 'reset' the iterator before
anthony25247ae2013-03-18 05:05:40 +0000107 * appending images, as only images from current image onward are
108 * appended together.
109 *
Anthony Thyssen5b7198d2016-12-20 11:05:09 +1000110 * Also note how a new wand is created by this operation, and that new
111 * wand does not inherit any settings from the previous wand (at least not
112 * at this time).
anthony25247ae2013-03-18 05:05:40 +0000113 */
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/*
Anthony Thyssen5b7198d2016-12-20 11:05:09 +1000126 * The above can be simplified further, though that is not what "magick"
127 * command would do which we are simulating.
anthony25247ae2013-03-18 05:05:40 +0000128 *
Anthony Thyssen5b7198d2016-12-20 11:05:09 +1000129 * Specifically you can read the 'rose' image directly on the end of of
130 * 'red' image wand. Then process just that rose image, even though it is
131 * sharing the same wand as another image.
anthony25247ae2013-03-18 05:05:40 +0000132 *
133 * Remember in MagickWand, simple image operators are only applied to the
134 * current image in the wand an to no other image! To apply a simple image
135 * operator (like MagickRotateImage()) to all the images in a wand you must
136 * iterate over all the images yourself.
137 */
138