MagickWand Examples
Posted: 2012-02-29T17:42:52-07:00
Subject: Clone and Append
Perhaps if you know another API you can contribute an example to me to be included.
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.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.
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.
*/