// 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() { 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("DISPLAY")) if err != nil { panic(err) } }
func (c Snappshot) Screenshot(res string) revel.Result { s := strings.Split(res, "x") width, _ := strconv.Atoi(s[0]) height, _ := strconv.Atoi(s[1]) imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() dw := imagick.NewDrawingWand() defer dw.Destroy() cw := imagick.NewPixelWand() cw2 := imagick.NewPixelWand() cw.SetColor("darkgray") cw2.SetColor("white") mw.NewImage(uint(width), uint(height), cw) dw.SetTextAlignment(imagick.ALIGN_CENTER) dw.SetFillColor(cw2) dw.SetFontSize(150) cw2.SetColor("black") dw.SetStrokeColor(cw2) dw.Annotation(float64(width)/2, float64(height)/2, res) mw.DrawImage(dw) mw.SetImageFormat("jpg") output := mw.GetImageBlob() return JPGImage(output) }
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") }
// 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 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") }
func getTextImage(text string, size int) []byte { imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() dw := imagick.NewDrawingWand() defer dw.Destroy() pw := imagick.NewPixelWand() defer pw.Destroy() l := len(text) w := size * 3 * (l + 6) h := size * 2 pw.SetColor("none") mw.NewImage(uint(w), uint(h), pw) pw.SetColor("white") dw.SetFillColor(pw) dw.SetFont("/usr/share/fonts/default/TrueType/msyh.ttf") dw.SetFontSize(float64(size)) dw.Annotation(0, float64(size), "ctrip © "+text) mw.DrawImage(dw) mw.TrimImage(0) mw.ResetImagePage("") cw := mw.Clone() pw.SetColor("black") mw.SetImageBackgroundColor(pw) mw.ShadowImage(100, 1, 0, 0) mw.CompositeImage(cw, imagick.COMPOSITE_OP_OVER, 1, 1) cw.Destroy() mw.SetImageFormat("PNG") return mw.GetImageBlob() }
// Set up the drawingwand "dw" for the given font name, font size, and colour. // If the font or size changes sx get the new width of a space // (the magickwand is required if it is necessary to query the font metrics) func draw_setfont(mw *imagick.MagickWand, dw *imagick.DrawingWand, font string, size float64, colour string, sx *float64) { sflag := false if len(font) > 0 { dw.SetFont(font) sflag = true } if len(colour) > 0 { pw := imagick.NewPixelWand() pw.SetColor(colour) dw.SetFillColor(pw) pw.Destroy() sflag = true } if size > 0 { dw.SetFontSize(size) } // If either the font or the fontsize (or both) have changed // we need to get the size of a space again if sflag { fm := mw.QueryFontMetrics(dw, " ") *sx = fm.TextWidth } }
// 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") }
// 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") }
func drawSetfont(mw *imagick.MagickWand, dw *imagick.DrawingWand) { dw.SetFont(randFont()) pw := imagick.NewPixelWand() pw.SetColor(colors[rand.Intn(len(colors))]) dw.SetFontWeight(500) dw.SetFillColor(pw) dw.SetFontSize(33) pw.Destroy() }
func proceedImages(i []os.FileInfo) { imagick.Initialize() defer imagick.Terminate() green := imagick.NewPixelWand() green.SetColor("#1cd000") none := imagick.NewPixelWand() none.SetColor("none") channel := imagick.CHANNEL_OPACITY for _, f := range i { importImage := imagick.NewMagickWand() importImage.ReadImage("./images/" + f.Name()) importImage.FloodfillPaintImage(channel, none, 20000, green, 0, 0, false) importImage.WriteImage("imagesDone/" + f.Name()) importImage.Destroy() } green.Destroy() none.Destroy() }
// Encode image to file (ImageMagick) func (c *Convertor) encodeImageMagick(i image.Image, filename string) (err error) { imagick.Initialize() mw := imagick.NewMagickWand() defer mw.Destroy() err = mw.ReadImageBlob(c.GetImageBytes(i)) if err != nil { fmt.Fprintf(os.Stderr, "Error ReadImageBlob: %v\n", err.Error()) return } if c.Opts.Grayscale { c := mw.GetImageColors() mw.QuantizeImage(c, imagick.COLORSPACE_GRAY, 8, true, true) } switch filepath.Ext(filename) { case ".png": mw.SetImageFormat("PNG") mw.WriteImage(filename) case ".tif": case ".tiff": mw.SetImageFormat("TIFF") mw.WriteImage(filename) case ".gif": mw.SetImageFormat("GIF") mw.WriteImage(filename) case ".bmp": w := imagick.NewPixelWand() w.SetColor("black") defer w.Destroy() cs := mw.GetImageColorspace() if c.Opts.Grayscale { cs = imagick.COLORSPACE_GRAY } mw.SetImageFormat("BMP3") mw.SetImageBackgroundColor(w) mw.SetImageAlphaChannel(imagick.ALPHA_CHANNEL_REMOVE) mw.SetImageAlphaChannel(imagick.ALPHA_CHANNEL_DEACTIVATE) mw.SetImageMatte(false) mw.SetImageCompression(imagick.COMPRESSION_NO) mw.QuantizeImage(16, cs, 8, true, true) mw.WriteImage(filename) default: mw.SetImageFormat("JPEG") mw.WriteImage(filename) } return }
func (pxd pixelData) save(dest string) error { bg := imagick.NewPixelWand() bg.SetColor("#E82A33") mw := imagick.NewMagickWand() mw.NewImage(uint(pxd.blockSize*pxd.columns), 1080, bg) mw.SetImageFormat("png") mw.DrawImage(pxd.wands.dw) mw.SetAntialias(false) err := mw.WriteImage(dest) return err }
// 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() 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 createMask(d uint, r float64) (mask *imagick.MagickWand) { mask = imagick.NewMagickWand() pw := imagick.NewPixelWand() defer pw.Destroy() dw := imagick.NewDrawingWand() defer dw.Destroy() pw.SetColor("none") mask.NewImage(d, d, pw) pw.SetColor("white") dw.SetFillColor(pw) dw.Circle(r, r, r-1, r*2-1) mask.DrawImage(dw) return }
func PixelVectorToImage(imgVector []float64, width, height int) []byte { 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(uint(width), uint(height), pw) mw.SetImageFormat("jpeg") // Get a new pixel iterator iterator := mw.NewPixelIterator() defer iterator.Destroy() pixelIndex := 0 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 _, pixel := range pixels { if !pixel.IsVerified() { panic("unverified pixel") } gray := imgVector[pixelIndex] hex := fmt.Sprintf("#%02x%02x%02x", int(gray), int(gray), int(gray)) if ret := pixel.SetColor(hex); !ret { panic("Could not set color in pixel") } pixelIndex++ } // Sync writes the pixels back to the mw if err := iterator.SyncIterator(); err != nil { panic(err) } } return mw.GetImageBlob() }
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") }
func speedLine(mw *imagick.MagickWand, aw *imagick.MagickWand) error { cols, rows := mw.GetImageHeight(), mw.GetImageWidth() dw := imagick.NewDrawingWand() defer dw.Destroy() cw := imagick.NewPixelWand() cw.SetColor(*color) dw.SetFillColor(cw) center := []float64{float64(rows) / 2.0, float64(cols) / 2.0} const radiusCenter float64 = 0.75 const step float64 = 0.02 const bold float64 = 1.0 var theeta float64 for theeta < math.Pi*2 { stepNoise := rand.Float64() + 0.5 theeta += step * stepNoise radiusCenterNoise := rand.Float64()*0.3 + 1.0 boldNoise := rand.Float64() + 0.7 + 0.3 point0 := imagick.PointInfo{ X: math.Sin(theeta)*center[0]*radiusCenter*radiusCenterNoise + center[0], Y: math.Cos(theeta)*center[1]*radiusCenter*radiusCenterNoise + center[1], } point1 := imagick.PointInfo{ X: math.Sin(theeta)*center[0]*2 + center[0], Y: math.Cos(theeta)*center[1]*2 + center[1], } point2 := imagick.PointInfo{ X: math.Sin(theeta+step*bold*boldNoise)*center[0]*2 + center[0], Y: math.Cos(theeta+step*bold*boldNoise)*center[1]*2 + center[1], } dw.Polygon([]imagick.PointInfo{point0, point1, point2}) } if err := aw.DrawImage(dw); err != nil { return err } return nil }
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 NewPixelizr(img string, targetRes int) (pixelData, error) { srcWand := imagick.NewMagickWand() err := srcWand.ReadImage(img) width, height := shrinkImage(srcWand, targetRes) return pixelData{ // data: px.([]uint8), rows: int(height), columns: int(width), blockSize: int(1080 / height), wands: wands{ src: srcWand, pw: imagick.NewPixelWand(), mw: imagick.NewMagickWand(), dw: imagick.NewDrawingWand(), }, }, err }
func CreatePictureFromVector(imgVector []float64, width, height int, path string) { newWand := imagick.NewPixelWand() defer newWand.Destroy() newWand.SetColor("white") newImg := imagick.NewMagickWand() defer newImg.Destroy() // Create a nXn image with a default of white newImg.NewImage(uint(width), uint(height), newWand) // Get a new pixel iterator iterator := newImg.NewPixelIterator() defer iterator.Destroy() var pixelIndex = 0 for y := 0; y < height; 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 _, pixel := range pixels { if !pixel.IsVerified() { panic("unverified pixel") } gray := imgVector[pixelIndex] hex := fmt.Sprintf("#%02x%02x%02x", int(gray), int(gray), int(gray)) if ret := pixel.SetColor(hex); !ret { panic("Could not set color in pixel") } pixelIndex++ } // Sync writes the pixels back to the mw if err := iterator.SyncIterator(); err != nil { panic(err) } } newImg.WriteImage(path) }
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") }
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") }
// 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 Make(path string) string { if IsURL(path) { path = Download(path) } // make file name base := filepath.Base(path) ext := filepath.Ext(path) basesize := len(base) extsize := len(ext) base = string([]rune(base)[0 : basesize-extsize]) ext = string([]rune(ext)[1:extsize]) if ext != "jpg" && ext != "gif" && ext != "png" { err := errors.New("unknow format") panic(err) } output := base + "_lgtm." + ext file, err := os.Open(path) if err != nil { panic(err) } defer file.Close() // adjust lgtm size conf, _, err := image.DecodeConfig(file) size := 0.0 if conf.Width > conf.Height { size = float64(conf.Height) / 3.0 * 0.75 } else { size = float64(conf.Width) / 3.0 * 0.75 } // prepare image imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() err = mw.ReadImage(path) if err != nil { panic(err) } // prepare text dw := imagick.NewDrawingWand() defer dw.Destroy() pw := imagick.NewPixelWand() defer pw.Destroy() pw.SetColor("white") dw.SetFont("/Library/Fonts/Impact.ttf") dw.SetFontSize(size) dw.SetTextKerning(size / 10) dw.SetFillColor(pw) dw.SetGravity(imagick.GRAVITY_CENTER) mw.SetFirstIterator() // draw text and save image := mw.CoalesceImages() image.AnnotateImage(dw, 0, 0, 0, "LGTM") for image.NextImage() { image.AnnotateImage(dw, 0, 0, 0, "LGTM") } image.OptimizeImageLayers() err = image.WriteImages(output, true) if err != nil { panic(err) } return output }
func main() { imagick.Initialize() defer imagick.Terminate() image := imagick.NewMagickWand() defer image.Destroy() pw := imagick.NewPixelWand() defer pw.Destroy() image.ReadImage("fract6.jpg") // scale it down w := image.GetImageWidth() h := image.GetImageHeight() pw.SetColor("transparent") if err := image.ShearImage(pw, 45, 0); err != nil { panic(err) } w = image.GetImageWidth() h = image.GetImageHeight() // scale it to make it look like it is laying down if err := image.ScaleImage(w, h/2); err != nil { panic(err) } // Get image stats w = image.GetImageWidth() h = image.GetImageHeight() // Make a blank canvas to draw on canvas := imagick.NewMagickWand() defer canvas.Destroy() // Use a colour from the input image pw, err := image.GetImagePixelColor(0, 0) if err != nil { panic(err) } canvas.NewImage(w, h*2, pw) offset := int(h) // The original drawing method was to go along each row from top to bottom so that // a line in the "front" (which is one lower down the picture) will be drawn over // one behind it. // The problem with this method is that every line is drawn even if it will be covered // up by a line "in front" of it later on. // The method used here goes up each column from left to right and only draws a line if // it is longer than everything drawn so far in this column and will therefore be visible. // With the new drawing method this takes 13 secs - the previous method took 59 secs // loop through all points in image for x := 0; x < int(w); x++ { // The PHP version created, used and destroyed the drawingwand inside // the inner loop but it is about 25% faster to do only the DrawLine // inside the loop line := imagick.NewDrawingWand() line_height := 0 for y := int(h) - 1; y >= 0; y-- { // get (r,g,b) and grey value pw, err := image.GetImagePixelColor(int(x), int(y)) if err != nil { continue } // 255* adjusts the rgb values to Q8 even if the IM being used is Q16 r := (int)(255 * pw.GetRed()) g := (int)(255 * pw.GetGreen()) b := (int)(255 * pw.GetBlue()) // Calculate grayscale - a divisor of 10-25 seems to work well. // grey = (r+g+b)/25 grey := (r + g + b) / 15 // grey = (r+g+b)/10 // Only draw a line if it will show "above" what's already been done if line_height == 0 || line_height < grey { line.SetFillColor(pw) line.SetStrokeColor(pw) // Draw the part of the line that is visible start_y := y + offset - line_height end_y := y - grey + offset line.Line(float64(x), float64(start_y), float64(x), float64(end_y)) line_height = grey } line_height-- } // Draw the lines on the image canvas.DrawImage(line) line.Destroy() } canvas.ScaleImage(w-h, h*2) // write canvas canvas.WriteImage("3d_fractal.jpg") }
func main() { imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() dw := imagick.NewDrawingWand() defer dw.Destroy() cw := imagick.NewPixelWand() diameter := uint(640) radius := float64(diameter / 2) cw.SetColor("white") mw.NewImage(diameter, diameter, cw) dw.SetStrokeOpacity(1) // circle and rectangle dw.PushDrawingWand() // Hmmmm. Very weird. rgb(0,0,1) draws a black line around the edge // of the circle as it should. But rgb(0,0,0) or black don't. // AND if I remove the PixelSetColor then it draws a white boundary // around the rectangle (and presumably around the circle too) cw.SetColor("rgb(0,0,1)") dw.SetStrokeColor(cw) dw.SetStrokeWidth(4) dw.SetStrokeAntialias(true) cw.SetColor("red") //dw.SetStrokeOpacity(1) dw.SetFillColor(cw) dw.Circle(radius, radius, radius, radius*2) dw.Rectangle(50, 13, 120, 87) dw.PopDrawingWand() // rounded rectangle dw.PushDrawingWand() points := []imagick.PointInfo{ {378.1, 81.72}, {381.1, 79.56}, {384.3, 78.12}, {387.6, 77.33}, {391.1, 77.11}, {394.6, 77.62}, {397.8, 78.77}, {400.9, 80.57}, {403.6, 83.02}, {523.9, 216.8}, {526.2, 219.7}, {527.6, 223}, {528.4, 226.4}, {528.6, 229.8}, {528, 233.3}, {526.9, 236.5}, {525.1, 239.5}, {522.6, 242.2}, {495.9, 266.3}, {493, 268.5}, {489.7, 269.9}, {486.4, 270.8}, {482.9, 270.9}, {479.5, 270.4}, {476.2, 269.3}, {473.2, 267.5}, {470.4, 265}, {350, 131.2}, {347.8, 128.3}, {346.4, 125.1}, {345.6, 121.7}, {345.4, 118.2}, {346, 114.8}, {347.1, 111.5}, {348.9, 108.5}, {351.4, 105.8}, {378.1, 81.72}, } dw.SetStrokeAntialias(true) dw.SetStrokeWidth(2.016) dw.SetStrokeLineCap(imagick.LINE_CAP_ROUND) dw.SetStrokeLineJoin(imagick.LINE_JOIN_ROUND) dw.SetStrokeDashArray(make([]float64, 0)) cw.SetColor("rgb(0,0,128)") // If strokecolor is removed completely then the circle is not there dw.SetStrokeColor(cw) // But now I've added strokeopacity - 1=circle there 0=circle not there // If opacity is 1 the black edge around the rectangle is visible dw.SetStrokeOpacity(1) // No effect // dw.SetFillRule(imagick.FILL_EVEN_ODD) // this doesn't affect the circle cw.SetColor("#c2c280") dw.SetFillColor(cw) // 1=circle there 0=circle there but rectangle fill disappears // dw.SetFillOpacity(0) dw.Polygon(points) dw.SetStrokeOpacity(1) dw.PopDrawingWand() // yellow polygon dw.PushDrawingWand() points = []imagick.PointInfo{ {540, 288}, {561.6, 216}, {547.2, 43.2}, {280.8, 36}, {302.4, 194.4}, {331.2, 64.8}, {504, 64.8}, {475.2, 115.2}, {525.6, 93.6}, {496.8, 158.4}, {532.8, 136.8}, {518.4, 180}, {540, 172.8}, {540, 223.2}, {540, 288}, } dw.SetStrokeAntialias(true) dw.SetStrokeWidth(5.976) dw.SetStrokeLineCap(imagick.LINE_CAP_ROUND) dw.SetStrokeLineJoin(imagick.LINE_JOIN_ROUND) dw.SetStrokeDashArray([]float64{}) cw.SetColor("#4000c2") dw.SetStrokeColor(cw) dw.SetFillRule(imagick.FILL_EVEN_ODD) cw.SetColor("#ffff00") dw.SetFillColor(cw) dw.Polygon(points) dw.PopDrawingWand() // rotated and translated ellipse // The DrawEllipse function only draws the ellipse with // the major and minor axes orthogonally aligned. This also // applies to some of the other functions such as DrawRectangle. // If you want an ellipse that has the major axis rotated, you // have to rotate the coordinate system before the ellipse is // drawn. And you'll also want the ellipse somewhere on the // image rather than at the top left (where the 0,0 origin is // located) so before drawing the ellipse we move the origin to // wherever we want the centre of the ellipse to be and then // rotate the coordinate system by the angle of rotation we wish // to apply to the ellipse and *then* we draw the ellipse. // NOTE that doing all this within PushDrawingWand()/PopDrawingWand() // means that the coordinate system will be restored after // the PopDrawingWand dw.PushDrawingWand() cw.SetColor("rgb(0,0,1)") dw.SetStrokeColor(cw) dw.SetStrokeWidth(2) dw.SetStrokeAntialias(true) cw.SetColor("orange") //dw.DrawSetStrokeOpacity(1) dw.SetFillColor(cw) // Be careful of the order in which you meddle with the // coordinate system! Rotating and then translating is // not the same as translating then rotating dw.Translate(radius/2, 3*radius/2) dw.Rotate(-30) dw.Ellipse(0, 0, radius/8, 3*radius/8, 0, 360) dw.PopDrawingWand() // A line from the centre of the circle // to the top left edge of the image dw.Line(0, 0, radius, radius) mw.DrawImage(dw) mw.WriteImage("chart_test.jpg") }
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("DISPLAY")); err != nil { panic(err) } }