Home | History | Annotate | Download | only in api_examples
      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 from 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 new
    111      * wand does not inherit any settings from the previous wand (at least not
    112      * at 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, though that is not what "magick"
    127  * command would do which we are simulating.
    128  *
    129  * 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.
    132  *
    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 
    139