go image/draw 生成圆形图片的问题

ccoding · · 3802 次点击
其实可以再简化一点,不用DrawMask; Image接口挺好玩 :smile: ``` go package main import( "fmt" "image" "image/png" "image/color" "math" "os" ) func main(){ Circle() } func Circle() { file, err := os.Create("newcircle.png") if err != nil { fmt.Println(err) } defer file.Close() imageFile , err := os.Open("background.png") if err != nil { fmt.Println(err) } defer imageFile.Close() srcImg, _ := png.Decode(imageFile) w := srcImg.Bounds().Max.X - srcImg.Bounds().Min.X h := srcImg.Bounds().Max.Y - srcImg.Bounds().Min.Y d := w if w > h { d = h } dstImg := NewCircleMask(srcImg, image.Point{d/4,d/4}, d/2) png.Encode(file, dstImg) } func NewCircleMask(img image.Image, p image.Point, d int) CircleMask { return CircleMask{img, p, d} } type CircleMask struct{ image image.Image point image.Point diameter int } func (ci CircleMask) ColorModel() color.Model { return ci.image.ColorModel() } func (ci CircleMask) Bounds() image.Rectangle { return image.Rect(0, 0, ci.diameter, ci.diameter) } func (ci CircleMask) At(x, y int) color.Color { d := ci.diameter dis := math.Sqrt(math.Pow(float64(x-d/2),2)+math.Pow(float64(y-d/2),2)) if dis > float64(d)/2 { return ci.image.ColorModel().Convert(color.RGBA{255, 255, 255, 0}) }else { return ci.image.At(ci.point.X + x, ci.point.Y + y) } } ```
#6
更多评论
简单实现了下 ``` go func Circle() { file, err := os.Create("newcircle.png") if err != nil { fmt.Println(err) } defer file.Close() imageFile , err := os.Open("background.png") if err != nil { fmt.Println(err) } defer imageFile.Close() srcImg, _ := png.Decode(imageFile) w := srcImg.Bounds().Max.X - srcImg.Bounds().Min.X h := srcImg.Bounds().Max.Y - srcImg.Bounds().Min.Y d := w if w > h { d = h } maskImg := circleMask(d) dstImg := image.NewRGBA(image.Rect(0,0,d,d)) draw.DrawMask(dstImg, srcImg.Bounds().Add(image.Pt(0,0)), srcImg, image.Pt((w-d)/2,(h-d)/2), maskImg,image.Pt(0,0),draw.Src) png.Encode(file, dstImg) } func circleMask(d int) image.Image{ img := image.NewRGBA(image.Rect(0,0,d,d)) for x:= 0;x<d;x++{ for y:= 0;y<d;y++{ dis := math.Sqrt(math.Pow(float64(x-d/2),2)+math.Pow(float64(y-d/2),2)) if dis > float64(d)/2 { img.Set(x,y,color.RGBA{255, 255, 255, 0}) }else { img.Set(x,y,color.RGBA{0, 0, 255, 255}) } } } return img } ``` 效果如下,不知道是不是你想要的效果 背景图: ![background.png](https://static.studygolang.com/181111/a05ecb880207fbebdbf8c37ba109848f.png) 圆形图: ![newcircle.png](https://static.studygolang.com/181111/36c1f1118a3eee6033b1bf774e4fa026.png)
#1
对的,非常感谢,就是我想要的效果,这个是非常实用的,尤其在小程序生成分享图片的时候很多需求会涉及到原型的头像,我以前都是用PHP 去生成,中间包括文字 头像 图片的合成布局,一旦访问量大了,PHP 直接就干的CPU 爆满,最近就一直在思索用GO是尝试重写图片生成这块 做成一个分布式的生成服务
#2