func main() { imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() lw := imagick.NewMagickWand() defer lw.Destroy() pw := imagick.NewPixelWand() defer pw.Destroy() dw := imagick.NewDrawingWand() defer dw.Destroy() // Create the initial 640x480 transparent canvas pw.SetColor("none") mw.NewImage(640, 480, pw) pw.SetColor("white") dw.SetFillColor(pw) dw.RoundRectangle(15, 15, 624, 464, 15, 15) mw.DrawImage(dw) lw.ReadImage("logo:") // Note that MagickSetImageCompose is usually only used for the MagickMontageImage // function and isn't used or needed by MagickCompositeImage mw.CompositeImage(lw, imagick.COMPOSITE_OP_SRC_IN, 0, 0) /* Write the new image */ mw.WriteImage("mask_result.png") }
// Example 2 // Rotate logo: 30 degrees around the point (300,100) // Since rotation is done around the origin, we must translate // the point (300,100) up to the origin, do the rotation, and // then translate back again // func example2() { imagick.Initialize() defer imagick.Terminate() t1 := make([]float64, 6) r := make([]float64, 6) t2 := make([]float64, 6) temp := make([]float64, 6) result := make([]float64, 6) mw := imagick.NewMagickWand() defer mw.Destroy() mw.ReadImage("logo:") // Initialize the required affines // translate (300,100) to origin set_translate_affine(t1, -300, -100) // rotate clockwise by 30 degrees set_rotate_affine(r, 30) // translate back again set_translate_affine(t2, 300, 100) // Now multiply the affine sequence // temp = t1*r affine_multiply(temp, t1, r) // result = temp*t2 affine_multiply(result, temp, t2) mw.DistortImage(imagick.DISTORTION_AFFINE_PROJECTION, result, false) mw.WriteImage("logo_affine_2.jpg") }
// Text effect 7 - Polar distortion func textEffect7() { imagick.Initialize() defer imagick.Terminate() // This one uses d_args[0] mw := imagick.NewMagickWand() defer mw.Destroy() dw := imagick.NewDrawingWand() defer dw.Destroy() pw := imagick.NewPixelWand() defer pw.Destroy() // Create a 320x200 transparent canvas pw.SetColor("none") mw.NewImage(320, 200, pw) // Set up a 72 point font dw.SetFont("Verdana-Bold-Italic") dw.SetFontSize(72) // Now draw the text dw.Annotation(25, 65, "Magick") // Draw the image on to the mw mw.DrawImage(dw) d_args[0] = 0.0 // DON'T FORGET to set the correct number of arguments here mw.DistortImage(imagick.DISTORTION_POLAR, d_args, true) //mw.ResetImagePage("") // Trim the image again mw.TrimImage(0) // Add the border pw.SetColor("none") mw.BorderImage(pw, 10, 10) // and write it mw.WriteImage("text_polar.png") }
// Text effect 2 - tiled text using the builtin checkerboard pattern // Anthony's Tiled Font effect func textEffect2() { imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() dw := imagick.NewDrawingWand() defer dw.Destroy() pw := imagick.NewPixelWand() defer pw.Destroy() setTilePattern(dw, "#check", "pattern:checkerboard") pw.SetColor("lightblue") // Create a new transparent image mw.NewImage(320, 100, pw) // Set up a 72 point font dw.SetFont("Verdana-Bold-Italic") dw.SetFontSize(72) // Now draw the text dw.Annotation(28, 68, "Magick") // Draw the image on to the mw mw.DrawImage(dw) // Trim the image mw.TrimImage(0) // Add a transparent border pw.SetColor("lightblue") mw.BorderImage(pw, 5, 5) // and write it mw.WriteImage("text_pattern.png") }
func main() { var err error imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() bg := imagick.NewPixelWand() defer bg.Destroy() fg := imagick.NewPixelWand() defer fg.Destroy() err = mw.ReadImage("http://www.imagemagick.org/Usage/images/cyclops_sm.gif") if err != nil { panic(err) } bg.SetColor("white") mw.BorderImage(bg, 1, 1) mw.SetImageAlphaChannel(imagick.ALPHA_CHANNEL_SET) fg.SetColor("none") channel := imagick.CHANNELS_RGB | imagick.CHANNEL_ALPHA // Floodfill the "background" colour with the "foreground" colour // starting at coordinate 0,0 using a fuzz of 20 mw.FloodfillPaintImage(channel, fg, 20, bg, 0, 0, false) mw.ShaveImage(1, 1) mw.DisplayImage(os.Getenv("DYSPLAY")) if err != nil { panic(err) } }
// Text effect 4 - bevelled font http://www.imagemagick.org/Usage/fonts/#bevel func textEffect4() { imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() dw := imagick.NewDrawingWand() defer dw.Destroy() pw := imagick.NewPixelWand() defer pw.Destroy() // Create a 320x100 canvas pw.SetColor("gray") mw.NewImage(320, 100, pw) // Set up a 72 point font dw.SetFont("Verdana-Bold-Italic") dw.SetFontSize(72) // Set up a 72 point white font pw.SetColor("white") dw.SetFillColor(pw) // Now draw the text dw.Annotation(25, 65, "Magick") // Draw the image on to the mw mw.DrawImage(dw) // the "gray" parameter must be true to get the effect shown on Anthony's page mw.ShadeImage(true, 140, 60) pw.SetColor("yellow") dw.SetFillColor(pw) cpw := imagick.NewPixelWand() defer cpw.Destroy() cpw.SetColor("gold") mw.ColorizeImage(pw, cpw) // and write it mw.WriteImage("text_bevel.png") }
func main() { // Note that the colours are stored as separate *normalized* RGB components arglist := []float64{ 0, 0, // RGB black 0, 0, 0, // The y coordinate is filled in later 0, -1, // RGB white 1, 1, 1, } // arguments for MagickFunctionImage funclist := []float64{4, -4, 1} imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() mw.ReadImage("beijing_md.jpg") // fill in the Y coordinate now that we can get the image dimensions arglist[6] = float64(mw.GetImageHeight() - 1) mw.SigmoidalContrastImage(true, 15, imagick.QUANTUM_RANGE*30/100) cw := mw.Clone() defer cw.Destroy() cw.SparseColorImage(imagick.CHANNELS_RGB, imagick.INTERPOLATE_BARYCENTRIC_COLOR, arglist) // Do the polynomial function cw.FunctionImage(imagick.FUNCTION_POLYNOMIAL, funclist) // -set option:compose:args 15 if err := cw.SetImageArtifact("compose:args", "15"); err != nil { panic(err) } mw.CompositeImage(cw, imagick.COMPOSITE_OP_BLUR, 0, 0) mw.WriteImage("beijing_model.jpg") }
// Text effect 3 - arc font (similar to http://www.imagemagick.org/Usage/fonts/#arc) func textEffect3() { imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() dw := imagick.NewDrawingWand() defer dw.Destroy() pw := imagick.NewPixelWand() defer pw.Destroy() // Create a 320x100 lightblue canvas pw.SetColor("lightblue") mw.NewImage(320, 100, pw) // Set up a 72 point font dw.SetFont("Verdana-Bold-Italic") dw.SetFontSize(72) // Now draw the text dw.Annotation(25, 65, "Magick") // Draw the image on to the mw mw.DrawImage(dw) mw.DistortImage(imagick.DISTORTION_ARC, dargs, false) // Trim the image mw.TrimImage(0) // Add the border pw.SetColor("lightblue") mw.BorderImage(pw, 10, 10) // and write it mw.WriteImage("text_arc.png") }
// Text effect 5 and 6 - Plain text and then Barrel distortion func textEffect5And6() { imagick.Initialize() defer imagick.Terminate() // This one uses d_args mw := imagick.NewMagickWand() defer mw.Destroy() dw := imagick.NewDrawingWand() defer dw.Destroy() pw := imagick.NewPixelWand() defer pw.Destroy() // Create a 320x100 transparent canvas pw.SetColor("none") mw.NewImage(320, 100, pw) // Set up a 72 point font dw.SetFont("Verdana-Bold-Italic") dw.SetFontSize(72) // Now draw the text dw.Annotation(25, 65, "Magick") // Draw the image on to the mw mw.DrawImage(dw) mw.WriteImage("text_plain.png") // Trim the image mw.TrimImage(0) // Add the border pw.SetColor("none") mw.BorderImage(pw, 10, 10) //mw.SetImageMatte(true) //mw.SetImageVirtualPixelMethod(TransparentVirtualPixelMethod) // d_args[0] = 0.1;d_args[1] = -0.25;d_args[2] = -0.25; [3] += .1 // The first value should be positive. If it is negative the image is *really* distorted d_args[0] = 0.0 d_args[1] = 0.0 d_args[2] = 0.5 // d_args[3] should normally be chosen such the sum of all 4 values is 1 // so that the result is the same size as the original // You can override the sum with a different value // If the sum is greater than 1 the resulting image will be smaller than the original d_args[3] = 1 - (d_args[0] + d_args[1] + d_args[2]) // Make the result image smaller so that it isn't as likely // to overflow the edges // d_args[3] += 0.1 // 0.0,0.0,0.5,0.5,0.0,0.0,-0.5,1.9 d_args[3] = 0.5 d_args[4] = 0.0 d_args[5] = 0.0 d_args[6] = -0.5 d_args[7] = 1.9 // DON'T FORGET to set the correct number of arguments here mw.DistortImage(imagick.DISTORTION_BARREL, d_args, true) //mw.ResetImagePage("") // Trim the image again mw.TrimImage(0) // Add the border pw.SetColor("none") mw.BorderImage(pw, 10, 10) // and write it mw.WriteImage("text_barrel.png") }
// Run starts the Halfshell program. Performs global (de)initialization, and // starts the HTTP server. func (h *Halfshell) Run() { var tmpl, _ = template.New("start").Parse(StartupTemplateString) _ = tmpl.Execute(os.Stdout, h) imagick.Initialize() defer imagick.Terminate() h.Server.ListenAndServe() }
func main() { imagick.Initialize() defer imagick.Terminate() // Current coordinates of text var dx, dy float64 // Width of a space in current font/size var sx float64 mw := imagick.NewMagickWand() dw := imagick.NewDrawingWand() // Set the size of the image mw.SetSize(300, 100) //mw.SetImageAlphaChannel(imagick.CHANNEL_ALPHA) mw.ReadImage("xc:white") // DO NOT SET GRAVITY - it makes text placement more complicated // (unless it does exactly what you wanted anyway). // Start near the left edge dx = 10 // If we know the largest font we're using, we can set the y coordinate // fairly accurately. In this case it is the 72 point Times font, so to // place the text such that the largest almost touches the top of the image // we just add the text height to the descender to give the coordinate for // our baseline. // In this case the largest is the 72 point Times-New-Roman so I'll use that // to compute the baseline dw.SetFontSize(72) dw.SetFont("Times-New-Roman") fm := mw.QueryFontMetrics(dw, "M") dy = fm.CharacterHeight + fm.Descender // Note that we must free up the fontmetric array once we're done with it // this draw_setfont(mw, dw, "Arial", 48, "#40FF80", &sx) draw_metrics(mw, dw, &dx, dy, sx, "this") // is // A NULL signals to draw_setfont that the font stays the same draw_setfont(mw, dw, "", 24, "#8040BF", &sx) draw_metrics(mw, dw, &dx, dy, sx, "is") // my draw_setfont(mw, dw, "Times-New-Roman", 18, "#BF00BF", &sx) draw_metrics(mw, dw, &dx, dy, sx, "my") // text draw_setfont(mw, dw, "", 72, "#0F0FBF", &sx) draw_metrics(mw, dw, &dx, dy, sx, "text") mw.DrawImage(dw) // Now write the magickwand image mw.WriteImage("metric1.gif") }
// Start the Halfshell program. Performs global (de)initialization, and // starts the HTTP server. func (h *Halfshell) Run() { var tmpl, _ = template.New("start").Parse(STARTUP_TEMPLATE_STRING) _ = tmpl.Execute(os.Stdout, h) imagick.Initialize() defer imagick.Terminate() h.Server.ListenAndServe() }
func main() { imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() aw := imagick.NewMagickWand() defer aw.Destroy() // Read the first input image if err := mw.ReadImage("bunny_grass.gif"); err != nil { panic(err) } // We need a separate wand to do this bit in parentheses if err := aw.ReadImage("bunny_anim.gif"); err != nil { panic(err) } aw.ResetImagePage("0x0+5+15!") // Now we have to add the images in the aw wand on to the end // of the mw wand. mw.AddImage(aw) // We can now destroy the aw wand so that it can be used // for the next operation aw.Destroy() // -coalesce aw = mw.CoalesceImages() // do "-delete 0" by copying the images from the "aw" wand to // the "mw" wand but omit the first one // free up the mw wand and recreate it for this step mw.Destroy() mw = imagick.NewMagickWand() for i := 1; i < int(aw.GetNumberImages()); i++ { aw.SetIteratorIndex(i) tw := aw.GetImage() mw.AddImage(tw) tw.Destroy() } mw.ResetIterator() aw.Destroy() // -deconstruct // Anthony says that MagickDeconstructImages is equivalent // to MagickCompareImagesLayers so we'll use that aw = mw.CompareImageLayers(imagick.IMAGE_LAYER_COMPARE_ANY) // -loop 0 aw.SetOption("loop", "0") // write the images into one file if err := aw.WriteImages("bunny_bgnd.gif", true); err != nil { panic(err) } }
// Example 4 // Create a rotated gradient // See: http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=12707 // The affine in this one is essentially the same as the one in Example 2 but // this example has a different use for the result func example4() { imagick.Initialize() defer imagick.Terminate() t1 := make([]float64, 6) r := make([]float64, 6) t2 := make([]float64, 6) temp := make([]float64, 6) result := make([]float64, 6) // Dimensions of the final rectangle w := uint(600) h := uint(100) // angle of clockwise rotation theta := 15.0 // degrees // Convert theta to radians rad_theta := DegreesToRadians(theta) // Compute the dimensions of the rectangular gradient gw := (uint)(float64(w)*math.Cos(rad_theta) + float64(h)*math.Sin(rad_theta) + 0.5) gh := (uint)(float64(w)*math.Sin(rad_theta) + float64(h)*math.Cos(rad_theta) + 0.5) // Don't let the rotation make the gradient rectangle any smaller // than the required output if gw < w { gw = w } if gh < h { gh = h } mw := imagick.NewMagickWand() defer mw.Destroy() mw.SetSize(gw, gh) mw.ReadImage("gradient:white-black") // Initialize the required affines // translate centre of gradient to origin set_translate_affine(t1, float64(-gw)/2.0, float64(-gh)/2.0) // rotate clockwise by theta degrees set_rotate_affine(r, theta) // translate back again set_translate_affine(t2, float64(gw)/2.0, float64(gh)/2.0) // Now multiply the affine sequences // temp = t1*r affine_multiply(temp, t1, r) // result = temp*t2 affine_multiply(result, temp, t2) mw.DistortImage(imagick.DISTORTION_AFFINE_PROJECTION, result, false) // Get the size of the distorted image and crop out the middle nw := mw.GetImageWidth() nh := mw.GetImageHeight() mw.CropImage(w, h, int((nw-w)/2), int((nh-h)/2)) mw.WriteImage("rotgrad_2.png") }
// Text effect 1 - shadow effect using MagickShadowImage // NOTE - if an image has a transparent background, adding a border of any colour other // than "none" will remove all the transparency and replace it with the border's colour func textEffect1() { imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() dw := imagick.NewDrawingWand() defer dw.Destroy() pw := imagick.NewPixelWand() defer pw.Destroy() pw.SetColor("none") // Create a new transparent image mw.NewImage(350, 100, pw) // Set up a 72 point white font pw.SetColor("white") dw.SetFillColor(pw) dw.SetFont("Verdana-Bold-Italic") dw.SetFontSize(72) // Add a black outline to the text pw.SetColor("black") dw.SetStrokeColor(pw) // Turn antialias on - not sure this makes a difference dw.SetTextAntialias(true) // Now draw the text dw.Annotation(25, 65, "Magick") // Draw the image on to the mw mw.DrawImage(dw) // Trim the image down to include only the text mw.TrimImage(0) // equivalent to the command line +repage mw.ResetImagePage("") // Make a copy of the text image cw := mw.Clone() // Set the background colour to blue for the shadow pw.SetColor("blue") mw.SetImageBackgroundColor(pw) // Opacity is a real number indicating (apparently) percentage mw.ShadowImage(70, 4, 5, 5) // Composite the text on top of the shadow mw.CompositeImage(cw, imagick.COMPOSITE_OP_OVER, 5, 5) cw.Destroy() cw = imagick.NewMagickWand() defer cw.Destroy() // Create a new image the same size as the text image and put a solid colour // as its background pw.SetColor("rgb(125,215,255)") cw.NewImage(mw.GetImageWidth(), mw.GetImageHeight(), pw) // Now composite the shadowed text over the plain background cw.CompositeImage(mw, imagick.COMPOSITE_OP_OVER, 0, 0) // and write the result cw.WriteImage("text_shadow.png") }
func main() { imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() mw.ReadImage("logo:") // We know that logo: is 640x480 but in the general case // we need to get the dimensions of the image w := mw.GetImageWidth() h := mw.GetImageHeight() // +matte is the same as -alpha off // This does it the "new" way but if your IM doesn't have this // then MagickSetImageMatte(mw,MagickFalse); can be used mw.SetImageAlphaChannel(imagick.ALPHA_CHANNEL_DEACTIVATE) // clone the input image mwr := mw.Clone() defer mwr.Destroy() // Resize it mwr.ResizeImage(w, h/2, imagick.FILTER_LANCZOS, 1) // Flip the image over to form the reflection mwr.FlipImage() // Create the gradient image which will be used as the alpha // channel in the reflection image mwg := imagick.NewMagickWand() defer mwg.Destroy() mwg.SetSize(w, h/2) mwg.ReadImage("gradient:white-black") // Copy the gradient in to the alpha channel of the reflection image mwr.CompositeImage(mwg, imagick.COMPOSITE_OP_COPY_OPACITY, 0, 0) // Add the reflection image to the wand which holds the original image mw.AddImage(mwr) // Append the reflection to the bottom (MagickTrue) of the original image mwout := mw.AppendImages(true) defer mwout.Destroy() // and save the result mwout.WriteImage("logo_reflect.png") }
func main() { imagick.Initialize() defer imagick.Terminate() pw := imagick.NewPixelWand() defer pw.Destroy() pw.SetColor("white") mw := imagick.NewMagickWand() defer mw.Destroy() // Create a 100x100 image with a default of white mw.NewImage(100, 100, pw) // Get a new pixel iterator iterator := mw.NewPixelIterator() defer iterator.Destroy() for y := 0; y < int(mw.GetImageHeight()); y++ { // Get the next row of the image as an array of PixelWands pixels := iterator.GetNextIteratorRow() if len(pixels) == 0 { break } // Set the row of wands to a simple gray scale gradient for x, pixel := range pixels { if !pixel.IsVerified() { panic("unverified pixel") } gray := x * 255 / 100 hex := fmt.Sprintf("#%02x%02x%02x", gray, gray, gray) if ret := pixel.SetColor(hex); !ret { panic("Could not set color in pixel") } } // Sync writes the pixels back to the mw if err := iterator.SyncIterator(); err != nil { panic(err) } } mw.WriteImage("bits_demo.gif") }
// Example 3 // Reflect the image about a line passing through the origin. // If the line makes an angle of D degrees with the horizontal // then this can be done by rotating the image by -D degrees so // that the line is now (in effect) the x axis, reflect the image // across the x axis, and then rotate everything back again. // In this example, rather than just picking an arbitrary angle, // let's say that we want the "logo:" image to be reflected across // it's own major diagonal. Although we know the logo: image is // 640x480 let's also generalize the code slightly so that it // will still work if the name of the input image is changed. // If the image has a width "w" and height "h", then the angle between // the x-axis and the major diagonal is atan(h/w) (NOTE that this // result is in RADIANS!) // For this example I will also retain the original dimensions of the // image so that anything that is reflected outside the borders of the // input image is lost func example3() { imagick.Initialize() defer imagick.Terminate() r1 := make([]float64, 6) reflect := make([]float64, 6) r2 := make([]float64, 6) temp := make([]float64, 6) result := make([]float64, 6) var angle_degrees float64 mw := imagick.NewMagickWand() defer mw.Destroy() mw.ReadImage("logo:") w := mw.GetImageWidth() h := mw.GetImageHeight() // Just convert the radians to degrees. This way I don't have // to write a function which sets up an affine rotation for an // argument specified in radians rather than degrees. // You can always change this. angle_degrees = RadiansToDegrees(math.Atan(float64(h) / float64(w))) // Initialize the required affines // Rotate diagonal to the x axis set_rotate_affine(r1, -angle_degrees) // Reflection affine (about x-axis) // In this case there isn't a specific function to set the // affine array (like there is for rotation and scaling) // so use the function which sets an arbitrary affine set_affine(reflect, 1, 0, 0, -1, 0, 0) // rotate image back again set_rotate_affine(r2, angle_degrees) // temp = r1*reflect affine_multiply(temp, r1, reflect) // result = temp*r2 affine_multiply(result, temp, r2) mw.DistortImage(imagick.DISTORTION_AFFINE_PROJECTION, result, false) mw.WriteImage("logo_affine_3.jpg") }
func main() { imagick.Initialize() defer imagick.Terminate() var err error mw := imagick.NewMagickWand() defer mw.Destroy() pw := imagick.NewPixelWand() defer pw.Destroy() pw.SetColor("blue") err = mw.ReadImage("logo:") if err != nil { panic(err) } w := int(mw.GetImageWidth()) h := int(mw.GetImageHeight()) mw.SetImageBackgroundColor(pw) // This centres the original image on the new canvas. // Note that the extent's offset is relative to the // top left corner of the *original* image, so adding an extent // around it means that the offset will be negative err = mw.ExtentImage(1024, 768, -(1024-w)/2, -(768-h)/2) if err != nil { panic(err) } // Set the compression quality to 95 (high quality = low compression) err = mw.SetImageCompressionQuality(95) if err != nil { panic(err) } mw.DisplayImage(os.Getenv("DYSPLAY")) if err != nil { panic(err) } }
func usePixelIterator() { imagick.Initialize() defer imagick.Terminate() /* Create a wand */ mw := imagick.NewMagickWand() defer mw.Destroy() /* Read the input image */ mw.ReadImage("logo:") // Get a one-pixel region at coordinate 200,100 iterator := mw.NewPixelRegionIterator(200, 100, 1, 1) defer iterator.Destroy() pixels := iterator.GetNextIteratorRow() // Modify the pixel pixels[0].SetColor("red") // then sync it back into the wand iterator.SyncIterator() mw.WriteImage("logo_pixel_iterator.gif") }
func main() { imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() mw.SetSize(100, 100) mw.ReadImage("plasma:red-yellow") make_tile(mw, "tile_plasma.png") mw.Destroy() mw = imagick.NewMagickWand() mw.SetSize(100, 100) mw.ReadImage("xc:") mw.AddNoiseImage(imagick.NOISE_RANDOM) mw.SetImageVirtualPixelMethod(imagick.VIRTUAL_PIXEL_TILE) mw.BlurImage(0, 10) mw.NormalizeImage() make_tile(mw, "tile_random.png") mw.Destroy() }
func main() { imagick.Initialize() // Schedule cleanup defer imagick.Terminate() var err error mw := imagick.NewMagickWand() // Schedule cleanup defer mw.Destroy() err = mw.ReadImage("logo:") if err != nil { panic(err) } // Get original logo size width := mw.GetImageWidth() height := mw.GetImageHeight() // Calculate half the size hWidth := uint(width / 2) hHeight := uint(height / 2) // Resize the image using the Lanczos filter // The blur factor is a float, where > 1 is blurry, < 1 is sharp err = mw.ResizeImage(hWidth, hHeight, imagick.FILTER_LANCZOS, 1) if err != nil { panic(err) } // Set the compression quality to 95 (high quality = low compression) err = mw.SetImageCompressionQuality(95) if err != nil { panic(err) } mw.DisplayImage(os.Getenv("DYSPLAY")) if err != nil { panic(err) } }
func main() { imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() mw.ReadImage("logo:") // A larger fuzz value allows more colours "near" white to be // modified. A fuzz of zero only allows an exact match with the // given colour // Set up the pixelwand containing the colour to be "targeted" // by transparency target := imagick.NewPixelWand() defer target.Destroy() target.SetColor("white") // Change the transparency of all colours which match target (with // fuzz applied). In this case they are made completely transparent (0) // but you can set this to any value from 0 to 1. mw.TransparentPaintImage(target, 0, 10, false) mw.WriteImage("logo_white.png") }
func useDraw() { imagick.Initialize() defer imagick.Terminate() /* Create a wand */ mw := imagick.NewMagickWand() defer mw.Destroy() /* Read the input image */ mw.ReadImage("logo:") fill := imagick.NewPixelWand() defer fill.Destroy() dw := imagick.NewDrawingWand() defer dw.Destroy() // Set the fill to "red" or you can do the same thing with this: fill.SetColor("red") dw.SetFillColor(fill) // Uses the current Fill as the colour of the point at 200,100 dw.Point(200, 100) mw.DrawImage(dw) /* write it */ mw.WriteImage("logo_pixel_drawingwand.gif") }
// Text effect 8 - Shepard's distortion func textEffect8() { imagick.Initialize() defer imagick.Terminate() // This one uses d_args[0] mw := imagick.NewMagickWand() defer mw.Destroy() dw := imagick.NewDrawingWand() defer dw.Destroy() pw := imagick.NewPixelWand() defer pw.Destroy() // Create a 320x200 transparent canvas pw.SetColor("none") mw.NewImage(640, 480, pw) // Set up a 72 point font dw.SetFont("Verdana-Bold-Italic") dw.SetFontSize(72) // Now draw the text dw.Annotation(50, 240, "Magick Rocks") // Draw the image on to the mw mw.DrawImage(dw) d_args[0] = 150.0 d_args[1] = 190.0 d_args[2] = 100.0 d_args[3] = 290.0 d_args[4] = 500.0 d_args[5] = 200.0 d_args[6] = 430.0 d_args[7] = 130.0 // DON'T FORGET to set the correct number of arguments here mw.DistortImage(imagick.DISTORTION_SHEPARDS, d_args, true) // Trim the image mw.TrimImage(0) // Add the border pw.SetColor("none") mw.BorderImage(pw, 10, 10) // and write it mw.WriteImage("text_shepards.png") }
func main() { imagick.Initialize() defer imagick.Terminate() dest := imagick.NewMagickWand() defer dest.Destroy() src := imagick.NewMagickWand() defer src.Destroy() mask := imagick.NewMagickWand() defer mask.Destroy() dest.SetSize(100, 100) src.SetSize(100, 100) if err := dest.ReadImage("tile:tile_water.jpg"); err != nil { panic(err) } if err := mask.ReadImage("mask_bite.png"); err != nil { panic(err) } // When you create a mask, you use white for those parts that you want // to show through and black for those which must not show through. // But internally it's the opposite so the mask must be negated mask.NegateImage(false) dest.SetImageClipMask(mask) if err := src.ReadImage("tile:tile_disks.jpg"); err != nil { panic(err) } // This does the src (overlay) over the dest (background) dest.CompositeImage(src, imagick.COMPOSITE_OP_OVER, 0, 0) dest.WriteImage("clip_out.jpg") }
// Example 1. // Rotate logo: by 90 degrees (about the origin), scale by 50 percent and // then move the image 240 in the x direction func example1() { imagick.Initialize() defer imagick.Terminate() s := make([]float64, 6) r := make([]float64, 6) t := make([]float64, 6) temp := make([]float64, 6) result := make([]float64, 6) mw := imagick.NewMagickWand() defer mw.Destroy() mw.ReadImage("logo:") // Set up the affine matrices // rotate 90 degrees clockwise set_rotate_affine(r, 90) // scale by .5 in x and y set_scale_affine(s, 0.5, 0.5) // translate to (240,0) set_translate_affine(t, 240, 0) // now multiply them - note the order in // which they are specified - in particular beware that // temp = r*s is NOT necessarily the same as temp = s*r //first do the rotation and scaling // temp = r*s affine_multiply(temp, r, s) // now the translation // result = temp*t affine_multiply(result, temp, t) // and then apply the result to the image mw.DistortImage(imagick.DISTORTION_AFFINE_PROJECTION, result, false) mw.WriteImage("logo_affine_1.jpg") }
func main() { imagick.Initialize() defer imagick.Terminate() var err error mw := imagick.NewMagickWand() defer mw.Destroy() // fillcolor and bordercolor fc, bc := imagick.NewPixelWand(), imagick.NewPixelWand() defer fc.Destroy() defer bc.Destroy() fc.SetColor("none") bc.SetColor("white") err = mw.ReadImage("logo:") if err != nil { panic(err) } rgba := imagick.CHANNELS_RGB | imagick.CHANNEL_ALPHA // The bordercolor (with fuzz of 20 applied) is replaced by the fill // colour starting at the given coordinate - in this case 0, 0. // Normally the last argument is false so that the colours are matched // but if it is true then it floodfills any pixel that does *not* match // the target color mw.FloodfillPaintImage(rgba, fc, 20, bc, 0, 0, false) mw.DisplayImage(os.Getenv("DYSPLAY")) if err != nil { panic(err) } }
func main() { imagick.Initialize() defer imagick.Terminate() /* First step is to create the gel shape: convert -size 100x60 xc:none \ -fill red -draw 'circle 25,30 10,30' \ -draw 'circle 75,30 90,30' \ -draw 'rectangle 25,15 75,45' \ gel_shape.png */ /* Create a wand */ mw := imagick.NewMagickWand() pw := imagick.NewPixelWand() dw := imagick.NewDrawingWand() mw.SetSize(100, 60) mw.ReadImage("xc:none") pw.SetColor("red") dw.SetFillColor(pw) dw.Circle(25, 30, 10, 30) dw.Circle(75, 30, 90, 30) dw.Rectangle(25, 15, 75, 45) // Now we draw the Drawing wand on to the Magick Wand mw.DrawImage(dw) mw.WriteImage("gel_shape.png") dw.Destroy() pw.Destroy() mw.Destroy() /* Next step is to create the gel highlight: convert gel_shape.png \ \( +clone -fx A +matte -blur 0x12 -shade 110x0 -normalize \ -sigmoidal-contrast 16,60% -evaluate multiply .5 \ -roll +5+10 +clone -compose Screen -composite \) \ -compose In -composite gel_highlight.png */ mw = imagick.NewMagickWand() mw.ReadImage("gel_shape.png") mwc := mw.Clone() mwf, err := mwc.FxImage("A") if err != nil { panic(err) } mwf.SetImageAlphaChannel(imagick.ALPHA_CHANNEL_DEACTIVATE) mwf.BlurImage(0, 12) mwf.ShadeImage(true, 110, 0) mwf.NormalizeImage() // The last argument is specified as a percentage on the command line // but is specified to the function as a percentage of the QuantumRange mwf.SigmoidalContrastImage(true, 16, 0.6*imagick.QUANTUM_RANGE) mwf.EvaluateImage(imagick.EVAL_OP_MULTIPLY, 0.5) mwf.RollImage(5, 10) mwc.Destroy() // The +clone operation copies the original but only so that // it can be used in the following composite operation, so we don't // actually need to do a clone, just reference the original image. mwf.CompositeImage(mw, imagick.COMPOSITE_OP_SCREEN, 0, 0) mw.CompositeImage(mwf, imagick.COMPOSITE_OP_IN, 0, 0) mw.WriteImage("gel_highlight.png") mw.Destroy() mwc.Destroy() mwf.Destroy() // Now create the gel border /* convert gel_highlight.png \ \( +clone -fx A +matte -blur 0x2 -shade 0x90 -normalize \ -blur 0x2 -negate -evaluate multiply .4 -negate -roll -.5-1 \ +clone -compose Multiply -composite \) \ -compose In -composite gel_border.png */ mw = imagick.NewMagickWand() mw.ReadImage("gel_highlight.png") mwc = mw.Clone() mwf, err = mwc.FxImage("A") if err != nil { panic(err) } mwf.SetImageAlphaChannel(imagick.ALPHA_CHANNEL_DEACTIVATE) mwf.BlurImage(0, 2) mwf.ShadeImage(true, 0, 90) mwf.NormalizeImage() mwf.BlurImage(0, 2) mwf.NegateImage(false) mwf.EvaluateImage(imagick.EVAL_OP_MULTIPLY, 0.4) mwf.NegateImage(false) mwf.RollImage(-1, -1) mwf.CompositeImage(mw, imagick.COMPOSITE_OP_MULTIPLY, 0, 0) mw.CompositeImage(mwf, imagick.COMPOSITE_OP_IN, 0, 0) mw.WriteImage("gel_border.png") mw.Destroy() mwc.Destroy() mwf.Destroy() // and finally the text and shadow effect /* convert gel_border.png \ -font Candice -pointsize 24 -fill white -stroke black \ -gravity Center -annotate 0 "Gel" -trim -repage 0x0+4+4 \ \( +clone -background navy -shadow 80x4+4+4 \) +swap \ -background none -flatten gel_button.png */ mw = imagick.NewMagickWand() dw = imagick.NewDrawingWand() pw = imagick.NewPixelWand() mw.ReadImage("gel_border.png") dw.SetFont("Lucida-Handwriting-Italic") dw.SetFontSize(24) pw.SetColor("white") dw.SetFillColor(pw) pw.SetColor("black") dw.SetStrokeColor(pw) dw.SetGravity(imagick.GRAVITY_CENTER) // It is important to notice here that MagickAnnotateImage renders the text on // to the MagickWand, NOT the DrawingWand. It only uses the DrawingWand for font // and colour information etc. mw.AnnotateImage(dw, 0, 0, 0, "Gel") mw.TrimImage(0) mw.ResetImagePage("0x0+4+4") mwc = mw.Clone() pw.SetColor("navy") mwc.SetImageBackgroundColor(pw) mwc.ShadowImage(80, 4, 4, 4) mwf = imagick.NewMagickWand() mwf.AddImage(mwc) mwf.AddImage(mw) mw.Destroy() mwc.Destroy() pw.SetColor("none") mwf.SetImageBackgroundColor(pw) mw = mwf.MergeImageLayers(imagick.IMAGE_LAYER_FLATTEN) mw.WriteImage("gel_button.png") mw.Destroy() mwc.Destroy() mwf.Destroy() dw.Destroy() pw.Destroy() }
func main() { imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() pw := imagick.NewPixelWand() defer pw.Destroy() dw := imagick.NewDrawingWand() defer dw.Destroy() if err := mw.SetSize(170, 100); err != nil { panic(err) } if err := mw.ReadImage("xc:black"); err != nil { panic(err) } pw.SetColor("white") dw.SetFillColor(pw) dw.Circle(50, 50, 13, 50) dw.Circle(120, 50, 157, 50) dw.Rectangle(50, 13, 120, 87) pw.SetColor("black") dw.SetFillColor(pw) dw.Circle(50, 50, 25, 50) dw.Circle(120, 50, 145, 50) dw.Rectangle(50, 25, 120, 75) pw.SetColor("white") dw.SetFillColor(pw) dw.Circle(60, 50, 40, 50) dw.Circle(110, 50, 130, 50) dw.Rectangle(60, 30, 110, 70) // Now we draw the Drawing wand on to the Magick Wand if err := mw.DrawImage(dw); err != nil { panic(err) } if err := mw.GaussianBlurImage(1, 1); err != nil { panic(err) } // Turn the matte of == +matte if err := mw.SetImageMatte(false); err != nil { panic(err) } if err := mw.WriteImage("logo_mask.png"); err != nil { panic(err) } mw.Destroy() dw.Destroy() pw.Destroy() mw = imagick.NewMagickWand() pw = imagick.NewPixelWand() dw = imagick.NewDrawingWand() mwc := imagick.NewMagickWand() defer mwc.Destroy() mw.ReadImage("logo_mask.png") pw.SetColor("red") dw.SetFillColor(pw) dw.Color(0, 0, imagick.PAINT_METHOD_RESET) mw.DrawImage(dw) mwc.ReadImage("logo_mask.png") mwc.SetImageMatte(false) mw.CompositeImage(mwc, imagick.COMPOSITE_OP_COPY_OPACITY, 0, 0) // Annotate gets all the font information from the drawingwand // but draws the text on the magickwand // Get the first available "*Sans*" font fonts := mw.QueryFonts("*Sans*") dw.SetFont(fonts[0]) dw.SetFontSize(36) pw.SetColor("white") dw.SetFillColor(pw) pw.SetColor("black") dw.SetStrokeColor(pw) dw.SetGravity(imagick.GRAVITY_CENTER) mw.AnnotateImage(dw, 0, 0, 0, "Ant") mw.WriteImage("logo_ant.png") mwc.Destroy() mw.Destroy() mw = imagick.NewMagickWand() if err := mw.ReadImage("logo_ant.png"); err != nil { panic(err) } mwf, err := mw.FxImage("A") if err != nil { panic(err) } defer mwf.Destroy() //mw.SetImageMatte(false) // +matte is the same as -alpha off mwf.SetImageAlphaChannel(imagick.ALPHA_CHANNEL_DEACTIVATE) mwf.BlurImage(0, 6) mwf.ShadeImage(true, 110, 30) mwf.NormalizeImage() // ant.png -compose Overlay -composite mwc = imagick.NewMagickWand() mwc.ReadImage("logo_ant.png") mwf.CompositeImage(mwc, imagick.COMPOSITE_OP_OVERLAY, 0, 0) mwc.Destroy() // ant.png -matte -compose Dst_In -composite mwc = imagick.NewMagickWand() mwc.ReadImage("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 mwf.SetImageAlphaChannel(imagick.ALPHA_CHANNEL_SET) mwf.CompositeImage(mwc, imagick.COMPOSITE_OP_DST_IN, 0, 0) mwf.WriteImage("logo_ant_3D.png") mw.Destroy() mwc.Destroy() mwf.Destroy() /* 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 = imagick.NewMagickWand() mw.ReadImage("logo_ant_3D.png") mwc = mw.Clone() pw.SetColor("navy") mwc.SetImageBackgroundColor(pw) mwc.ShadowImage(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 = imagick.NewMagickWand() mwf.AddImage(mwc) mwf.AddImage(mw) mwc.Destroy() pw.SetColor("none") mwf.SetImageBackgroundColor(pw) mwc = mwf.MergeImageLayers(imagick.IMAGE_LAYER_MERGE) mwc.WriteImage("logo_shadow_3D.png") mw.Destroy() mwc.Destroy() mwf.Destroy() /* 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 = imagick.NewMagickWand() mw.ReadImage("logo_shadow_3D.png") mwc = mw.Clone() // +repage mwc.ResetImagePage("") // +matte is the same as -alpha off mwc.SetImageAlphaChannel(imagick.ALPHA_CHANNEL_DEACTIVATE) mwf, err = mwc.FxImage("rand()") if err != nil { panic(err) } mwf.ShadeImage(true, 120, 30) pw.SetColor("grey70") // It seems that this must be a separate pixelwand for Colorize to work! pwo := imagick.NewPixelWand() defer pwo.Destroy() // AHA .. this is how to do a 60% colorize pwo.SetColor("rgb(60%,60%,60%)") mwf.ColorizeImage(pw, pwo) pw.SetColor("lavender") // and this is a 100% tint pwo.SetColor("rgb(100%,100%,100%)") mwf.TintImage(pw, pwo) mwc.Destroy() mwc = imagick.NewMagickWand() mwc.AddImage(mwf) mwc.AddImage(mw) mwf = mwc.MergeImageLayers(imagick.IMAGE_LAYER_FLATTEN) if err := mwf.DisplayImage(os.Getenv("DYSPLAY")); err != nil { panic(err) } }