最近接了个比较大的需求,须要作不少图片处理的事情,好比图片的旋转裁截拼接,各类渐变处理,文字排列,一开始光是想一想就头疼。但没有办法,既然已经需求已经到手上了,那就得把它作好才行,因而便开始被迫营业,无证上岗了。git
通过一番查找,找到了一个Go语言图片处理的库,通过调研发现还挺强的,能知足需求,因而决定写点文章,记录一下使用心得,以便往后不时之需。github
使用以前,咱们固然得先来安装一下这个库:app
go get -u github.com/fogleman/gg
这个库的一个好处是有不少测试代码,能够拿来跑跑看,就知道它大概能实现什么样的效果了。测试
这是它例子的大概效果图,能够看到,能实现的图形效果仍是挺多的。.net
咱们拿其中的一个代码来简单体验一下:3d
package main import "github.com/fogleman/gg" func main() { dc := gg.NewContext(1000, 1000) dc.DrawCircle(500, 500, 400) dc.SetRGB(0, 0, 0) dc.Fill() dc.SavePNG("out.png") }
duang 的一下,一张黑不溜秋的圆形图就生成了。code
关于上面的代码,下面会进行逐一说明。对象
dc := gg.NewContext(1000, 1000)
这是先初始化一个 Context
对象,使用库以前都须要先初始化一个 Context
对象,后面的两个 1000
,分别对应着最终生成图片的宽度和高度。咱们能够修改一下高度为 500
看看效果。blog
dc := gg.NewContext(1000, 500)
能够看到图片被腰斩了,高度矮了一半,一样修改宽度参数也能够获得相似的效果,这里就不演示了。图片
dc.DrawCircle(500, 500, 400)
这里是画一个圆心位置在 (500,500)
,半径为 400
的圆形。须要说明的一点是,这里的坐标轴是以左上角为原点的,水平向右是横轴正方向,竖直向下是纵轴正方向,因此(500,500)
正是中心位置。咱们能够调整一下参数值来看下效果。
dc := gg.NewContext(1000, 1000) dc.DrawCircle(300, 300, 400)
能够看到,圆心往左上角移动了。还能够调整一下半径参数试试:
dc := gg.NewContext(1000, 1000) dc.DrawCircle(300, 300, 300)
这样咱们又获得了一个完整的圆。
dc.SetRGB(0, 0, 0) dc.Fill()
这两句的意思是先设置颜色值为 (0,0,0)
,也就是黑色,乍眼一看这三个值分别对应的是颜色的 R、G、B
值,但实际上彻底不是这么回事,这里须要注意的是,这三个值分别表明红色、绿色、蓝色的程度,因此若是分别设置为,会获得下面的三张图。
那若是想要根据RGB值来设置颜色该怎么处理呢?其实也很简单,作一个压缩映射便可,RGB
值的范围是0~255,表示的含义也是对应色值的程度,这里不过将范围变成了0~1,那咱们将须要使用到的值除以255就能够获得对应的映射值了。具体的颜色RGB值跟颜色的对应关系能够在网上搜到。
https://tool.oschina.net/commons?type=3
下面咱们用淡黄色作一个例子,对应的 RGB
值是 (255,222,173)
,咱们添加一下映射转换的代码便可:
var rbgConverter = func(r []float64) []float64 { result := make([]float64, 0) for i := 0; i < len(r); i++ { result = append(result, r[i] / 255) } return result } func main() { dc := gg.NewContext(1000, 1000) dc.DrawCircle(500, 500, 400) rgb := []float64{255,222,173} newRgb := rbgConverter(rgb) dc.SetRGB(newRgb[0], newRgb[1], newRgb[2]) dc.Fill() dc.SavePNG("out.png") }
这样咱们就获得了一张黄图。
dc.SavePNG("out.png")
SavePNG()
方法能够将当前图形保存成 PNG
格式文件,路径能够是相对路径,也能够是绝对路径。
SaveJPG()
方法能够将当前图形保存成 JPG
格式文件。
固然,这里的两个方法其实也只是包装了一下,点进代码能够看到,里面并无什么奇奇怪怪的逻辑。
// SavePNG encodes the image as a PNG and writes it to disk. func (dc *Context) SavePNG(path string) error { return SavePNG(path, dc.im) } func SavePNG(path string, im image.Image) error { file, err := os.Create(path) if err != nil { return err } defer file.Close() return png.Encode(file, im) }
因此,咱们也能够根据本身的须要将图片保存成其它格式或者存到其它地方。
加载图片有三个方法能够实现,LoadPNG()
用来加载 PNG
格式的图片,LoadJPG()
用来加载 JPG
格式的图片,若是不清楚该用什么方法,能够直接使用 LoadImage()
方法来加载图片。
加载图片后,获得的是一个 image.Image
对象,能够经过该对象来获取图片的一些基本信息,如:图片的长和宽、图片某一点的颜色RGB值。
加载图片以后,能够使用 DrawImage()
方法来将图片绘制出来,以便用于后续操做。
im, err := gg.LoadImage("/Users/bytedance/Desktop/test.jpg") if err != nil { panic(err) } w := im.Bounds().Size().X h := im.Bounds().Size().Y dc := gg.NewContext(h, w) dc.DrawImage(im, 0, 0)
有一个常常使用到的方法叫 Clip()
,该方法能够将图像进行裁剪,裁剪的形状取决于以前画的图形。
下面来举个例子,这是咱们要裁剪的图,咱们用一个圆形来对它进行裁剪。
func main() { // 加载图片,这里路径换成本身的 im, err := gg.LoadImage("test.jpg") if err != nil { panic(err) } // 获取图片的宽度和高度 w := im.Bounds().Size().X h := im.Bounds().Size().Y dc := gg.NewContext(h, w) // 取宽度和高度的最小值做为直径 radius := math.Min(float64(w), float64(h)) / 2 // 画圆形 dc.DrawCircle(float64(w/2), float64(h/2), radius) // 对画布进行裁剪 dc.Clip() // 加载图片 dc.DrawImage(im, 0, 0) dc.SavePNG("out.png") }
这样一来,头像就作好了【手动狗头】。
Go 语言也能够实现对图片进行不少类型的操做,今天主要介绍了图片的加载、保存、绘制圆形、调整大小和颜色以及裁剪。以后还会进一步介绍其它功能。
我以为若是不是须要使用并无熟悉它的必要,但知道有这么个东西,知道它能实现什么样的效果,可让你手上的牌又多了一张,之后有须要的时候便不至于捉襟见肘了。因此还在等什么,赶忙点赞收藏加关注吧~