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") }
func main() { flag.Parse() imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() var err error if flag.NArg() < 1 { fmt.Println("Usage: imagick_profiles <imgfile> [<proftype>]\n") os.Exit(1) } basename := flag.Arg(0) err = mw.ReadImage(basename) if err != nil { fmt.Println("ReadImage Error:", err) os.Exit(1) } if flag.NArg() == 1 { profs := mw.GetImageProfiles("*") fmt.Println(profs) } else { proftype := flag.Arg(1) prof := mw.GetImageProfile(proftype) fmt.Print(prof) } }
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) } }
// 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 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") }
// 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") }
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") }
func main() { imagick.Initialize() defer imagick.Terminate() // Start chunking workers imagesChan := make(chan []byte) for i := 0; i < chunkersCnt; i++ { go scheduleChunking(imagesChan) } // Start token store cleaner go tokenStoreCleaner(time.Tick(tokenCleanup)) // Serve Assets http.Handle("/css/", http.FileServer(http.Dir("./assets"))) http.Handle("/js/", http.FileServer(http.Dir("./assets"))) http.Handle("/fonts/", http.FileServer(http.Dir("./assets"))) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { switch { case r.Method == "POST" && r.URL.Path == "/": handlePost(imagesChan, w, r) case r.Method == "GET" && r.URL.Path == "/": handleGetIndex(w, r) default: log.Println("404: ", r.URL.Path) http.NotFound(w, r) } }) log.Println("Server started") log.Fatal(http.ListenAndServe(":8080", nil)) }
func TestResize(t *testing.T) { imagick.Initialize() defer imagick.Terminate() tests := []*ResizeCase{ {"fixture/circle.png", 30, 150}, } if err := os.Mkdir("test-out", os.ModeDir|os.ModePerm); os.IsNotExist(err) { t.Fatal(err) } for i, x := range tests { before, err := ioutil.ReadFile(x.filename) if err != nil { t.Fatal(err) } after, err := Resize(before, x.w, x.h) if err != nil { t.Fatal(err) } filename := fmt.Sprintf("test-out/resize-%dx%d-%d%s", x.w, x.h, i, filepath.Ext(x.filename)) err = ioutil.WriteFile(filename, after, os.ModePerm) if err != nil { t.Fatal(err) } } }
// 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") }
// 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") }
func Draw(text string, name string) { imagick.Initialize() defer imagick.Terminate() // Current coordinates of text var dx float64 = 20 mw := imagick.NewMagickWand() dw := imagick.NewDrawingWand() defer mw.Destroy() defer dw.Destroy() // Set the size of the image mw.SetSize(285, 50) mw.ReadImage("../assets/images/bg.gif") // Start near the left edge dw.SetFontSize(40) // Note that we must free up the fontmetric array once we're done with it list := strings.Split(text, " ") for _, item := range list { writeWord(mw, dw, &dx, item) } mw.DrawImage(dw) // Now write the magickwand image mw.WriteImage(name) }
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() }
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) }
// Extracts thumbnail func (c *Convertor) ExtractThumbnail(file string, info os.FileInfo) { c.CurrFile += 1 cover, err := c.GetCoverImage(file, info) if err != nil { fmt.Fprintf(os.Stderr, "Error GetCoverImage: %v\n", err.Error()) return } if err != nil { fmt.Fprintf(os.Stderr, "Error Thumbnail: %v\n", err.Error()) return } if c.Opts.Width > 0 || c.Opts.Height > 0 { if c.Opts.Fit { cover = imaging.Fit(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter]) } else { cover = imaging.Resize(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter]) } } else { cover = imaging.Resize(cover, 256, 0, filters[c.Opts.Filter]) } imagick.Initialize() mw := imagick.NewMagickWand() defer mw.Destroy() b := new(bytes.Buffer) png.Encode(b, cover) err = mw.ReadImageBlob(b.Bytes()) if err != nil { fmt.Fprintf(os.Stderr, "Error ReadImageBlob: %v\n", err.Error()) } var fileuri string var filename string if c.Opts.Outfile == "" { fileuri = "file://" + file filename = filepath.Join(c.Opts.Outdir, fmt.Sprintf("%x.png", md5.Sum([]byte(fileuri)))) } else { abs, _ := filepath.Abs(c.Opts.Outfile) fileuri = "file://" + abs filename = abs } mw.SetImageFormat("PNG") mw.SetImageProperty("Software", "CBconvert") mw.SetImageProperty("Description", "Thumbnail of "+fileuri) mw.SetImageProperty("Thumb::URI", fileuri) mw.SetImageProperty("Thumb::MTime", strconv.FormatInt(info.ModTime().Unix(), 10)) mw.SetImageProperty("Thumb::Size", strconv.FormatInt(info.Size(), 10)) mw.SetImageProperty("Thumb::Mimetype", mime.TypeByExtension(filepath.Ext(file))) mw.WriteImage(filename) }
// 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 main() { imagick.Initialize() // Schedule cleanup defer imagick.Terminate() http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) }
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") }
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") }
func main() { imagick.Initialize() mw = imagick.NewMagickWand() defer mw.Destroy() h := histogram(os.Args[0]) enc := json.NewEncoder(os.Stdout) enc.Encode(h) }
func Resize(w, h uint, blob []byte) []byte { imagick.Initialize() defer imagick.Terminate() wand := imagick.NewMagickWand() defer wand.Destroy() _ = wand.ReadImageBlob(blob) wand.ResizeImage(w, h, imagick.FILTER_LANCZOS2_SHARP, 1) return wand.GetImageBlob() }
func (ng Engine) Initialize(tmpDir string) error { if tmpDir != "" { if err := os.MkdirAll(tmpDir, 0755); err != nil { return err } ng.tmpDir = tmpDir os.Setenv("MAGICK_TMPDIR", tmpDir) ng.SweepTmpDir() } imagick.Initialize() return nil }
// 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 NewContext(cfgFile string) (*ZContext, error) { //初始化imagemagick imagick.Initialize() //加载配置config.ini文件 cfg, err := LoadConfig(cfgFile) if err != nil { return nil, err } //log日志 var log *ZLogger logOutput := cfg.System.LogOutput if logOutput == "file" { log, err = NewFileLogger("gimg", 0, cfg.System.LogName) } else if logOutput == "console" { log, err = NewLogger("gimg", 0) } else { return nil, fmt.Errorf("初始化logo日志失败!") } if err != nil { return nil, err } //cache缓存 var cache *ZCache if cfg.Cache.Cache == 1 { // var client *memcache.Client // cacheAddr := fmt.Sprintf("%s:%d", cfg.Cache.MemcacheHost, cfg.Cache.MemcachePort) // client = memcache.New(cacheAddr) cache = NewCache(cfg.Cache.MemcacheHost, cfg.Cache.MemcachePort) } else { cache = nil } //初始化imagemagick img := NewImage() //redisDB缓存 redisDB, err := NewRedisDB(cfg.Storage.SsdbHost, cfg.Storage.SsdbPort) if err != nil { return nil, err } return &ZContext{Config: cfg, Logger: log, Cache: cache, Image: img, Redis: redisDB, }, nil }
func init() { imagick.Initialize() ImageHandler.Func = imageHandler num := runtime.NumCPU() * 4 requestContexts = make(RequestContexts, num) for i := 0; i < num; i++ { requestContexts <- &RequestContext{ Wand: imagick.NewMagickWand(), } } }
func init() { rand.Seed(time.Now().UTC().UnixNano()) log.SetFlags(log.Flags() | log.Llongfile) //currentDir, _ := filepath.Abs(filepath.Dir(os.Args[0])) filePath = flag.String("f", "/home/joakim/Go/src/github.com/joakimp1/gofaces", "Path to images.") flag.Parse() imagick.Initialize() defer imagick.Terminate() }
// Actually placed screenshot onto background image func placeit(image_id string, xml_data Result, image []byte) string { imagick.Initialize() defer imagick.Terminate() width, _ := strconv.Atoi(xml_data.Device.Resolution.Width) height, _ := strconv.Atoi(xml_data.Device.Resolution.Height) x_positions := make([]int, 4) x_positions[0], _ = strconv.Atoi(xml_data.Device.Placement.Top_left_x) x_positions[1], _ = strconv.Atoi(xml_data.Device.Placement.Top_right_x) x_positions[2], _ = strconv.Atoi(xml_data.Device.Placement.Bottom_right_x) x_positions[3], _ = strconv.Atoi(xml_data.Device.Placement.Bottom_left_x) y_positions := make([]int, 4) y_positions[0], _ = strconv.Atoi(xml_data.Device.Placement.Top_left_y) y_positions[1], _ = strconv.Atoi(xml_data.Device.Placement.Top_right_y) y_positions[2], _ = strconv.Atoi(xml_data.Device.Placement.Bottom_right_y) y_positions[3], _ = strconv.Atoi(xml_data.Device.Placement.Bottom_left_y) base_x := x_positions[0] base_y := y_positions[0] result := []float64{0, 0, float64(x_positions[0] - base_x), float64(y_positions[0] - base_y), float64(width), 0, float64(x_positions[1] - base_x), float64(y_positions[1] - base_y), float64(width), float64(height), float64(x_positions[2] - base_x), float64(y_positions[2] - base_y), 0, float64(height), float64(x_positions[3] - base_x), float64(y_positions[3] - base_y)} mw := imagick.NewMagickWand() defer mw.Destroy() back_mw := imagick.NewMagickWand() defer back_mw.Destroy() mw.ReadImageBlob(image) back_mw.ReadImage("src/github.com/JustinJudd/go_snappshot/public/images/backgrounds/" + image_id + ".jpg") mw.SetImageVirtualPixelMethod(imagick.VIRTUAL_PIXEL_TRANSPARENT) mw.DistortImage(imagick.DISTORTION_PERSPECTIVE, result, true) sort.IntSlice.Sort(x_positions) sort.IntSlice.Sort(y_positions) back_mw.CompositeImage(mw, imagick.COMPOSITE_OP_OVER, x_positions[0], y_positions[0]) placed_id := strconv.Itoa(int(time.Now().UnixNano())) back_mw.WriteImage(getGeneratedPath(placed_id)) return placed_id }
// 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 Thumbnail(filename string, targetWidth, targetHeight uint) { imagick.Initialize() defer imagick.Terminate() mw := imagick.NewMagickWand() defer mw.Destroy() var err error // 画像読み込み err = mw.ReadImage(filename) if err != nil { panic(err) } // 縦横サイズを取得 width, height := mw.GetImageWidth(), mw.GetImageHeight() // 縦横の小さい方に合わせてリサイズしたときのサイズを取得 resizedWidth, resizedHeight := getResizedWH(width, height, targetWidth, targetHeight) // サムネイルを作成 err = mw.ThumbnailImage(resizedWidth, resizedHeight) if err != nil { panic(err) } // 切り抜き開始位置 startX, startY := getStartPointXY(width, height, resizedWidth, resizedHeight) // 最終的なサイズで切り抜く err = mw.ExtentImage(targetWidth, targetHeight, startX, startY) if err != nil { panic(err) } // 画像のクオリティ err = mw.SetImageCompressionQuality(95) if err != nil { panic(err) } // ファイルに保存 // TODO(hfunai): ファイル名にドットがあると死亡 err = mw.WriteImage(strings.Replace(filename, ".", "_thumb.", 1)) if err != nil { panic(err) } }