I've been looking at the MagickWand API and I have two questions.
1. I see the CloneMagickWand method makes an exact copy of a wand. Given a wand with several images, how would I go about creating a new wand that contains a subset of those images? For example, given wand A containing 4 images, create wand B that is otherwise-identical but contains only images 2 and 3.
2. My memory is that a cloned image shares the pixel cache with the original image until one of the images tries to modify a pixel, at which point the cache is duplicated. That is, the pixel cache has copy-on-write semantics. Is that correct?
Where I'm going with this is that I'd like to be able to read a multi-image file into a wand, select one or more of the images into a new wand, and then do some operations on the new wand. It would be useful if there was only one copy of the pixel data as long as neither wand modifies the pixels.
Cloning and the MagickWand API
Re: Cloning and the MagickWand API
As you mentioned, cloning is light weight. Each clone increments the reference count to the original pixel cache and a new cache is created only when you signal your intention to update the pixels.
You can create a subset of images from a wand using existing methods shown in wandtest.c:
We could create a convenience method but by using the existing methods as shown above your code will be backwards compatible.
You can create a subset of images from a wand using existing methods shown in wandtest.c:
Code: Select all
(void) fprintf(stdout,"Iterate forward...\n");
MagickResetIterator(magick_wand);
while (MagickNextImage(magick_wand) != MagickFalse)
(void) fprintf(stdout,"index %ld scene %lu\n",
MagickGetIteratorIndex(magick_wand),MagickGetImageScene(magick_wand));
(void) fprintf(stdout,"Iterate reverse...\n");
while (MagickPreviousImage(magick_wand) != MagickFalse)
(void) fprintf(stdout,"index %ld scene %lu\n",
MagickGetIteratorIndex(magick_wand),MagickGetImageScene(magick_wand));
(void) fprintf(stdout,"Remove scene 1...\n");
(void) MagickSetIteratorIndex(magick_wand,1);
clone_wand=MagickGetImage(magick_wand);
status=MagickRemoveImage(magick_wand);
if (status == MagickFalse)
ThrowAPIException(magick_wand);
MagickResetIterator(magick_wand);
while (MagickNextImage(magick_wand) != MagickFalse)
(void) fprintf(stdout,"index %ld scene %lu\n",
MagickGetIteratorIndex(magick_wand),MagickGetImageScene(magick_wand));
(void) fprintf(stdout,"Insert scene 1 back in sequence...\n");
(void) MagickSetIteratorIndex(magick_wand,0);
status=MagickAddImage(magick_wand,clone_wand);
if (status == MagickFalse)
ThrowAPIException(magick_wand);
while (MagickNextImage(magick_wand) != MagickFalse)
(void) fprintf(stdout,"index %ld scene %lu\n",
MagickGetIteratorIndex(magick_wand),MagickGetImageScene(magick_wand));
(void) fprintf(stdout,"Set scene 2 to scene 1...\n");
(void) MagickSetIteratorIndex(magick_wand,2);
status=MagickSetImage(magick_wand,clone_wand);
clone_wand=DestroyMagickWand(clone_wand);
if (status == MagickFalse)
ThrowAPIException(magick_wand);
MagickResetIterator(magick_wand);
while (MagickNextImage(magick_wand) != MagickFalse)
(void) fprintf(stdout,"index %ld scene %lu\n",
MagickGetIteratorIndex(magick_wand),MagickGetImageScene(magick_wand));
Re: Cloning and the MagickWand API
Perfect. Thanks! I agree, this code is better than a convenience method.