From: anthony Date: Mon, 18 Mar 2013 05:05:40 +0000 (+0000) Subject: The same ImageMagick example, using many different API's X-Git-Tag: 7.0.1-0~4059 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=25247ae04ca6720329dae43dda55ff9c35564bba;p=imagemagick The same ImageMagick example, using many different API's --- diff --git a/api_examples/README b/api_examples/README new file mode 100644 index 000000000..6fd8a79d4 --- /dev/null +++ b/api_examples/README @@ -0,0 +1,32 @@ + +Every program in this directory is the equivelent of this Shell API +command... + + magick -size 100x100 xc:red \ + \( rose: -rotate -90 \) \ + +append show: + + +Command should be expanded to show a simple image operation on a +list of images! + + + +Each however does so in its own way using various functions in the +ImageMagick Library. + +Shell API... + + magick.sh A simple "magick" shell command (as above) + magick_script As a "magick" script file + +MagickCLI API... + + magick_command.c As a argument list to the MagickCommand function + cli_process.c Using the function that processes a argument list + cli_operators.c Using operator groups to process individual options + +MagickWand API... + + wand.c usaing a MagickWand + diff --git a/api_examples/cli_operators.c b/api_examples/cli_operators.c new file mode 100644 index 000000000..7cff593a6 --- /dev/null +++ b/api_examples/cli_operators.c @@ -0,0 +1,53 @@ +/* + Make direct calls to process the various CLI option handling groups + as defined in "MagickWand/operators.c" which uses a special + MagickCLI type of 'wand'. + + This is essentually the calls 'ProcessCommandOptions()' make + though without as many error and sanity checks. + + Compile with ImageMagick-devlop installed... + + gcc -lMagickWand -lMagickCore cli_operators.c -o cli_operators + + Compile and run directly in Source Directory... + + IM_PROG=api_examples/cli_operators + gcc -I`pwd` -LMagickWand/.libs -LMagickCore/.libs \ + -lMagickWand -lMagickCore $IM_PROG.c -o $IM_PROG + + sh magick.sh $IM_PROG + + +*/ +#include +#include "MagickCore/studio.h" +#include "MagickWand/MagickWand.h" +#include "MagickWand/operation.h" + +int main(int argc, char **argv) +{ + MagickCLI + *cli_wand; + + MagickCoreGenesis(argv[0],MagickFalse); + + cli_wand = AcquireMagickCLI((ImageInfo *)NULL,(ExceptionInfo *)NULL); + + CLISettingOptionInfo (cli_wand, "-size", "100x100"); + CLISpecialOperator (cli_wand, "-read", "xc:red"); + CLISpecialOperator (cli_wand, "(", NULL); + CLISpecialOperator (cli_wand, "-read", "rose:"); + CLISimpleOperatorImages (cli_wand, "-rotate", "-90", NULL); + CLISpecialOperator (cli_wand, ")", NULL); + CLIListOperatorImages (cli_wand, "+append", NULL, NULL); + CLIListOperatorImages (cli_wand, "-write", "show:", NULL); + + /* Note use of 'True' to report all exceptions - including fatals */ + if ( CLICatchException(cli_wand,MagickTrue) != MagickFalse ) + fprintf(stderr, "Major Error Detected\n"); + + cli_wand = DestroyMagickCLI(cli_wand); + + MagickCoreTerminus(); +} diff --git a/api_examples/cli_process.c b/api_examples/cli_process.c new file mode 100644 index 000000000..e7be3b2eb --- /dev/null +++ b/api_examples/cli_process.c @@ -0,0 +1,50 @@ +/* + Direct call to ProcessCommandOptions() to process an array of + options minus the command argument. This is the function that + actually splits up the argument array into separate operation + group calls. + + + Compile with ImageMagick-devlop installed... + + gcc -lMagickWand -lMagickCore cli_process.c -o cli_process + + Compile and run directly in Source Directory... + + IM_PROG=api_examples/cli_process + gcc -I`pwd` -LMagickWand/.libs -LMagickCore/.libs \ + -lMagickWand -lMagickCore $IM_PROG.c -o $IM_PROG + + sh magick.sh $IM_PROG + +*/ +#include +#include "MagickCore/studio.h" +#include "MagickWand/MagickWand.h" + +int main(int argc, char **argv) +{ + MagickCLI + *cli_wand; + + int arg_count; + char *args[] = { "-size", "100x100", "xc:red", + "(", "rose:", "-rotate", "-90", ")", + "+append", "show:", NULL }; + + for(arg_count = 0; args[arg_count] != (char *)NULL; arg_count++); + + + MagickCoreGenesis(argv[0],MagickFalse); + cli_wand = AcquireMagickCLI((ImageInfo *)NULL,(ExceptionInfo *)NULL); + + ProcessCommandOptions(cli_wand, arg_count, args, 0, MagickCommandOptionFlags); + + /* Note use of 'True' to report all exceptions - including non-fatals */ + if ( CLICatchException(cli_wand,MagickTrue) != MagickFalse ) + fprintf(stderr, "Major Error Detected\n"); + + + cli_wand = DestroyMagickCLI(cli_wand); + MagickCoreTerminus(); +} diff --git a/api_examples/magick.sh b/api_examples/magick.sh new file mode 100755 index 000000000..8ee4b1d11 --- /dev/null +++ b/api_examples/magick.sh @@ -0,0 +1,4 @@ +#!/bin/sh +magick -size 100x100 xc:red \ + \( rose: -rotate -90 \) \ + +append show: diff --git a/api_examples/magick_command.c b/api_examples/magick_command.c new file mode 100644 index 000000000..c732cbe6a --- /dev/null +++ b/api_examples/magick_command.c @@ -0,0 +1,56 @@ +/* + Direct call to MagickImageCommand(), + which is basically what the "magick" command does via + a wrapper function MagickCommandGenesis() + + Compile with ImageMagick-devlop installed... + + gcc -lMagickWand -lMagickCore magick_command.c -o magick_command + + Compile and run directly in Source Directory... + + IM_PROG=api_examples/magick_command + gcc -I`pwd` -LMagickWand/.libs -LMagickCore/.libs \ + -lMagickWand -lMagickCore $IM_PROG.c -o $IM_PROG + + sh magick.sh $IM_PROG + +*/ +#include +#include "MagickCore/studio.h" +#include "MagickCore/exception.h" +#include "MagickCore/exception-private.h" +#include "MagickCore/image.h" +#include "MagickWand/MagickWand.h" +#include "MagickWand/magick-cli.h" + +int main(int argc, char **argv) +{ + MagickCoreGenesis(argv[0],MagickFalse); + + { + MagickBooleanType status; + + ImageInfo *image_info = AcquireImageInfo(); + ExceptionInfo *exception = AcquireExceptionInfo(); + + int arg_count; + char *args[] = { "magick", "-size", "100x100", "xc:red", + "(", "rose:", "-rotate", "-90", ")", + "+append", "show:", NULL }; + + for(arg_count = 0; args[arg_count] != (char *)NULL; arg_count++); + + (void) MagickImageCommand(image_info, arg_count, args, NULL, exception); + + if (exception->severity != UndefinedException) + { + CatchException(exception); + fprintf(stderr, "Major Error Detected\n"); + } + + image_info=DestroyImageInfo(image_info); + exception=DestroyExceptionInfo(exception); + } + MagickCoreTerminus(); +} diff --git a/api_examples/magick_script b/api_examples/magick_script new file mode 100755 index 000000000..db96d91cb --- /dev/null +++ b/api_examples/magick_script @@ -0,0 +1,35 @@ +#!/bin/env magick-script +# +# Magick Script +# +-size 100x100 xc:red +( rose: -rotate -90 ) ++append -write show: + +# exit - not really needed here -- more for pipelines and debugging +-exit +------------------------------------------------------------------------------- +This area is completely ignored by the magick script. + +If you want you can put uncommented documentation such as Perl POD +which reformat such documentation into many different doc formats. +A bit like what Imagemagick does not Images! + +Or you can just put any old rubbish -- much like this :-) + +It could even be binary, image data or something else! +Hmmm Image Data may be useful -- perhaps in the future +Remind me sometime! + +Anthony Thyssen - Author/Developer for + Imagemagick Examples + ImageMagick Shell/Script API + Morphology Operator + Distort Operator + Composite Method Redevelopment + GIF Animation Methods + +------------------------------------------------------------------------------- + "Mr. Worf, scan that ship." "Aye, Captain... 300 DPI?" +------------------------------------------------------------------------------- + diff --git a/api_examples/wand.c b/api_examples/wand.c new file mode 100644 index 000000000..7d4e2e653 --- /dev/null +++ b/api_examples/wand.c @@ -0,0 +1,137 @@ +/* + Implementation of a CLI command using a MagickWand API + + magick -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=api_examples/wand + gcc -I`pwd` -LMagickWand/.libs -LMagickCore/.libs \ + -lMagickWand -lMagickCore $IM_PROG.c -o $IM_PROG + + sh magick.sh $IM_PROG + +*/ +#include +#include "MagickWand/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, and that want + * does not inherit any settings from the previous wand (at least not at + * this time). + */ + + /* 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. + */ +