Page 1 of 1
mpr: within -draw
Posted: 2008-10-10T08:03:11-07:00
by rmabry
Hi folks,
I'm compositing a large number of small images onto various positions of a large image and I'm running into memory issues and inefficiency. The number of composites is in the thousands, but the actual number of files generating the small images is relatively small. Each small image is resized via the size specified within the -draw string (e.g., to size 60x60 here:)
Code: Select all
-draw "image Darken 100,100 60,60 'tile117.jpg'"
Thousands of similar draw strings are stored in a file "drawstrings.txt" and I execute a command like
Code: Select all
convert -size 6000,8175 xc:white -draw @drawstrings.txt out.png
This leads to an unnecessarily large number of resize operations, because there are only a few hundred images involved (tile001.jpg, tile002.jpg, etc.)
I could use virtual images via mpr: but that doesn't seem permissible (or is it?) within a -draw string, which seems to accept only a filename.
Any ideas? (I'll be working on a Perl script in the meantime, but it would be nice to have such options on the command line.)
Thanks,
Rick
Re: mpr: within -draw
Posted: 2008-10-10T13:35:51-07:00
by magick
The -draw image primitive accepts any / all image types supported by ImageMagick including MPR and inline images (i.e. starts with DATA: and includes a base64-encoded string). You could get some speed up if the tile is used often at a particular dimension and it pre-resized. The best solution is probably to implement this using one of the ImageMagick API's (e.g. MagickWand) or scripting language (e.g. PerlMagick). Our recommendation is the Pixel View methods of MagickWand. It runs in parallel so if you have a dual-core or quad-core processor you can get a 2-4x speed-up.
Re: mpr: within -draw
Posted: 2008-10-10T18:43:59-07:00
by rmabry
Thanks for the (as usual) speedy reply.
> The -draw image primitive accepts any / all image types supported by ImageMagick including MPR
Yup -- it was a string quoting-within-quotes issue. Sorry for the bother.
> inline images (i.e. starts with DATA: and includes a base64-encoded string)
Now that is very cool --- it gets Magicker and Magicker.
I appreciate the other advice and I'll look into using MagickWand, which is still magick to me. I'm still using the old API.
Rick
Re: mpr: within -draw
Posted: 2008-10-10T19:42:04-07:00
by magick
We have a sample program that utilizes the pixel view API which is way cool. It removes most of the complication when dealing with image pixels. To composite tiles, use TransferPixelViewIterator() which permits you to read pixels from one magick wand (the tile) and place it anywhere on the destination wand.
Save the code as
sigmoidal-contrast.c and build with this command:
- cc `MagickWand-config --cflags --cppflags` -o sigmoidal-contrast sigmoidal-contrast.c `MagickWand-config --ldflags --libs`
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <wand/MagickWand.h>
static MagickBooleanType SigmoidalContrast(PixelView *pixel_view,
void *context)
{
#define QuantumScale ((MagickRealType) 1.0/(MagickRealType) QuantumRange)
#define SigmoidalContrast(x) \
(QuantumRange*(1.0/(1+exp(10.0*(0.5-QuantumScale*x)))-0.0066928509)*1.0092503)
MagickPixelPacket
pixel;
PixelWand
**pixels;
register long
x;
pixels=GetPixelViewPixels(contrast_view);
for (x=0; x < (long) GetPixelViewWidth(contrast_view); x++)
{
PixelGetMagickColor(pixels[x],&pixel);
pixel.red=SigmoidalContrast(pixel.red);
pixel.green=SigmoidalContrast(pixel.green);
pixel.blue=SigmoidalContrast(pixel.blue);
pixel.index=SigmoidalContrast(pixel.index);
PixelSetMagickColor(contrast_pixels[x],&pixel);
}
return(MagickTrue);
}
int main(int argc,char **argv)
{
#define ThrowWandException(wand) \
{ \
char \
*description; \
\
ExceptionType \
severity; \
\
description=MagickGetException(wand,&severity); \
(void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
description=(char *) MagickRelinquishMemory(description); \
exit(-1); \
}
MagickBooleanType
status;
MagickPixelPacket
pixel;
MagickWand
*contrast_wand;
PixelView
*contrast_view;
if (argc != 3)
{
(void) fprintf(stdout,"Usage: %s image sigmoidal-image\n",argv[0]);
exit(0);
}
/*
Read an image.
*/
MagickWandGenesis();
contrast_wand=NewMagickWand();
status=MagickReadImage(contrast_wand,argv[1]);
if (status == MagickFalse)
ThrowWandException(contrast_wand);
/*
Sigmoidal non-linearity contrast control.
*/
contrast_view=NewPixelView(contrast_wand);
if (contrast_view == (PixelView *) NULL)
ThrowWandException(contrast_wand);
status=UpdatePixelViewIterator(contrast_view,SigmoidalContrast,(void *) NULL);
if (status == MagickFalse)
ThrowWandException(contrast_wand);
contrast_view=DestroyPixelView(contrast_view);
/*
Write the image then destroy it.
*/
status=MagickWriteImages(contrast_wand,argv[2],MagickTrue);
if (status == MagickFalse)
ThrowWandException(contrast_wand);
contrast_wand=DestroyMagickWand(contrast_wand);
MagickWandTerminus();
return(0);
}
Re: mpr: within -draw
Posted: 2008-10-14T18:44:17-07:00
by anthony
magick wrote:Inline images (i.e. starts with DATA: and includes a base64-encoded string).
Now THAT is cool. and one I did not know about!!!
An no wonder it isn't listed by
That would be more useful for reading images from MVG files, as
rmabry is doing and for ImageMagick API's than command line use, otherwise command line limits could start to overflow shell limits.
Hopefully the IM v7 idea for 'streaming' options would be able to make more use of this.
Now for a small example for IM examples!
If I can get it working.
Hmmm. this fails...
Code: Select all
convert data:`convert -size 4x4 xc:red -depth 8 ppm:- | gmime-uuencode --base64 - | sed '$d; 1d;' | tr -d ' \012'` x:
convert: unable to open image `data:UDYKNCA0CjI1NQr/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAA=': No such file or directory.
convert: missing an image filename `x:'.
I don't think it is even recognizing 'data'.
Suggestions about using data: is it restricted to MVG only?
Re: mpr: within -draw
Posted: 2008-10-14T20:39:31-07:00
by magick
We added inline: as a supported format. Will need a day or to ensure it actually works.