MagickWand Examples

The MagickWand interface is a new high-level C API interface to ImageMagick core methods. We discourage the use of the core methods and encourage the use of this API instead. Post MagickWand questions, bug reports, and suggestions to this forum.
Post Reply
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

MagickWand Examples

Post by anthony »

Subject: Clone and Append
anthony wrote:I created a small MagickWand test script to test out various things,
All seems to work as expected (once i checked the manual for each function)

https://dl.dropbox.com/u/9500683/append_test.c.txt

See the comments in the script about how to use MagickAddImage() (image list append)
and MagickAppendImages() (image layout append), which I gleaned from the manual, code, and some testing.
Because of the above I have been generating a series of 'equivalent' programs, which all do exactly same processing, but does so in as many ImageMagick API techniques as I have been comfortable with.

Code: Select all

/*
   Implementation of a CLI command using a MagickWand API

     convert -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 in Source Directory...

       IM_PROG=wand_test
       gcc -I`pwd` -Lwand/.libs -Lmagick/.libs \
         -lMagickWand -lMagickCore  $IM_PROG.c -o $IM_PROG

       sh magick.sh    ./$IM_PROG

*/
#include <stdio.h>
#include "wand/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!
     */

    /* Final output */
    status = MagickWriteImage(output,"show:");
    if (status == MagickFalse)
      ThrowWandException(output);

    output = DestroyMagickWand(output);

    MagickWandTerminus();
}

/*
 * The above can be simplified further.
 *
 * Specifically you can read the 'rose' image directly into the '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.
 */
Perhaps if you know another API you can contribute an example to me to be included.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply