// Last updated 2008/11/04 11:22 // Better 3-D Logo Generation example // https://imagemagick.dev.org.tw/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(); }