// Last updated 2008/11/04 11:22
// Better 3-D Logo Generation example
// https://imagemagick.org.cn/Usage/advanced/#3d-logos-2
#include <windows.h>
#include <wand/magick_wand.h>
void test_wand(void)
{
MagickWand *mw = NULL;
MagickWand *mwc = NULL;
MagickWand *mwf = NULL;
DrawingWand *dw = NULL;
PixelWand *pw = NULL;
PixelWand *pwo = NULL;
MagickWandGenesis();
/*
convert -size 170x100 xc:black \
-fill white -draw 'circle 50,50 13,50' \
-draw 'circle 120,50 157,50' \
-draw 'rectangle 50,13 120,87' \
-fill black -draw 'circle 50,50 25,50' \
-draw 'circle 120,50 145,50' \
-draw 'rectangle 50,25 120,75' \
-fill white -draw 'circle 60,50 40,50' \
-draw 'circle 110,50 130,50' \
-draw 'rectangle 60,30 110,70' \
-gaussian 1x1 +matte logo_mask.png
*/
/* Create a wand */
mw = NewMagickWand();
pw = NewPixelWand();
dw = NewDrawingWand();
MagickSetSize(mw,170,100);
MagickReadImage(mw,"xc:black");
PixelSetColor(pw,"white");
DrawSetFillColor(dw,pw);
DrawCircle(dw,50,50,13,50);
DrawCircle(dw,120,50,157,50);
DrawRectangle(dw,50,13,120,87);
PixelSetColor(pw,"black");
DrawSetFillColor(dw,pw);
DrawCircle(dw,50,50,25,50);
DrawCircle(dw,120,50,145,50);
DrawRectangle(dw,50,25,120,75);
PixelSetColor(pw,"white");
DrawSetFillColor(dw,pw);
DrawCircle(dw,60,50,40,50);
DrawCircle(dw,110,50,130,50);
DrawRectangle(dw,60,30,110,70);
// Now we draw the Drawing wand on to the Magick Wand
MagickDrawImage(mw,dw);
MagickGaussianBlurImage(mw,1,1);
// Turn the matte of == +matte
MagickSetImageMatte(mw,MagickFalse);
MagickWriteImage(mw,"logo_mask.png");
/* Tidy up */
if(mw)mw = DestroyMagickWand(mw);
if(dw)dw = DestroyDrawingWand(dw);
if(pw)pw = DestroyPixelWand(pw);
mw = NewMagickWand();
mwc = NewMagickWand();
pw = NewPixelWand();
dw = NewDrawingWand();
/*
convert ant_mask.png -fill red -draw 'color 0,0 reset' \
ant_mask.png +matte -compose CopyOpacity -composite \
-font Candice -pointsize 36 -fill white -stroke black \
-gravity Center -annotate 0 "Ant" \
ant.png
*/
MagickReadImage(mw,"logo_mask.png");
PixelSetColor(pw,"red");
DrawSetFillColor(dw,pw);
DrawColor(dw,0,0,ResetMethod);
MagickDrawImage(mw,dw);
MagickReadImage(mwc,"logo_mask.png");
MagickSetImageMatte(mwc,MagickFalse);
MagickCompositeImage(mw,mwc,CopyOpacityCompositeOp,0,0);
// Annotate gets all the font information from the drawingwand
// but draws the text on the magickwand
// I haven't got the Candice font so I'll use a pretty one
// that I know I have
DrawSetFont(dw,"Lucida-Handwriting-Italic");
DrawSetFontSize(dw,36);
PixelSetColor(pw,"white");
DrawSetFillColor(dw,pw);
PixelSetColor(pw,"black");
DrawSetStrokeColor(dw,pw);
DrawSetGravity(dw,CenterGravity);
MagickAnnotateImage(mw,dw,0,0,0,"Ant");
MagickWriteImage(mw,"logo_ant.png");
mwc = DestroyMagickWand(mwc);
mw = DestroyMagickWand(mw);
/*
convert ant.png -fx A +matte -blur 0x6 -shade 110x30 -normalize \
ant.png -compose Overlay -composite \
ant.png -matte -compose Dst_In -composite \
ant_3D.png
*/
mw = NewMagickWand();
MagickReadImage(mw,"logo_ant.png");
mwf = MagickFxImage(mw,"A");
// MagickSetImageMatte(mw,MagickFalse);
// +matte is the same as -alpha off
MagickSetImageAlphaChannel(mwf,DeactivateAlphaChannel);
MagickBlurImage(mwf,0,6);
MagickShadeImage(mwf,MagickTrue,110,30);
MagickNormalizeImage(mwf);
// ant.png -compose Overlay -composite
mwc = NewMagickWand();
MagickReadImage(mwc,"logo_ant.png");
MagickCompositeImage(mwf,mwc,OverlayCompositeOp,0,0);
mwc = DestroyMagickWand(mwc);
// ant.png -matte -compose Dst_In -composite
mwc = NewMagickWand();
MagickReadImage(mwc,"logo_ant.png");
// -matte is the same as -alpha on
// I don't understand why the -matte in the command line
// does NOT operate on the image just read in (logo_ant.png in mwc)
// but on the image before it in the list
// It would appear that the -matte affects each wand currently in the
// command list because applying it to both wands gives the same result
MagickSetImageAlphaChannel(mwf,SetAlphaChannel);
MagickSetImageAlphaChannel(mwc,SetAlphaChannel);
MagickCompositeImage(mwf,mwc,DstInCompositeOp,0,0);
MagickWriteImage(mwf,"logo_ant_3D.png");
if(mw)mw = DestroyMagickWand(mw);
if(mwc)mwc = DestroyMagickWand(mwc);
if(mwf)mwf = DestroyMagickWand(mwf);
/* Now for the shadow
convert ant_3D.png \( +clone -background navy -shadow 80x4+6+6 \) +swap \
-background none -layers merge +repage ant_3D_shadowed.png
*/
mw = NewMagickWand();
MagickReadImage(mw,"logo_ant_3D.png");
mwc = CloneMagickWand(mw);
PixelSetColor(pw,"navy");
MagickSetImageBackgroundColor(mwc,pw);
MagickShadowImage(mwc,80,4,6,6);
// at this point
// mw = ant_3D.png
// mwc = +clone -background navy -shadow 80x4+6+6
// To do the +swap I create a new blank MagickWand and then
// put mwc and mw into it. ImageMagick probably doesn't do it
// this way but it works here and that's good enough for me!
mwf = NewMagickWand();
MagickAddImage(mwf,mwc);
MagickAddImage(mwf,mw);
mwc = DestroyMagickWand(mwc);
PixelSetColor(pw,"none");
MagickSetImageBackgroundColor(mwf,pw);
mwc = MagickMergeImageLayers(mwf,MergeLayer);
MagickWriteImage(mwc,"logo_shadow_3D.png");
if(mw)mw = DestroyMagickWand(mw);
if(mwc)mwc = DestroyMagickWand(mwc);
if(mwf)mwf = DestroyMagickWand(mwf);
/*
and now for the fancy background
convert ant_3D_shadowed.png \
\( +clone +repage +matte -fx 'rand()' -shade 120x30 \
-fill grey70 -colorize 60 \
-fill lavender -tint 100 \) -insert 0 \
-flatten ant_3D_bg.jpg
*/
mw = NewMagickWand();
MagickReadImage(mw,"logo_shadow_3D.png");
mwc = CloneMagickWand(mw);
// +repage
MagickResetImagePage(mwc,"");
// +matte is the same as -alpha off
MagickSetImageAlphaChannel(mwc,DeactivateAlphaChannel);
mwf = MagickFxImage(mwc,"rand()");
MagickShadeImage(mwf,MagickTrue,120,30);
PixelSetColor(pw,"grey70");
// It seems that this must be a separate pixelwand for Colorize to work!
pwo = NewPixelWand();
// AHA .. this is how to do a 60% colorize
PixelSetColor(pwo,"rgb(60%,60%,60%)");
MagickColorizeImage(mwf,pw,pwo);
PixelSetColor(pw,"lavender");
// and this is a 100% tint
PixelSetColor(pwo,"rgb(100%,100%,100%)");
MagickTintImage(mwf,pw,pwo);
mwc = DestroyMagickWand(mwc);
mwc = NewMagickWand();
MagickAddImage(mwc,mwf);
MagickAddImage(mwc,mw);
mwf = DestroyMagickWand(mwf);
mwf = MagickMergeImageLayers(mwc,FlattenLayer);
MagickWriteImage(mwf,"logo_bg_3D.jpg");
/* Tidy up */
if(mw)mw = DestroyMagickWand(mw);
if(mwc)mwc = DestroyMagickWand(mwc);
if(mwf)mwf = DestroyMagickWand(mwf);
if(dw)dw = DestroyDrawingWand(dw);
if(pw)pw = DestroyPixelWand(pw);
if(pwo)pwo = DestroyPixelWand(pwo);
MagickWandTerminus();
}