【Go语言绘图】gg 库的基本使用
最近接了个比较大的需求,需要做很多图片处理的事情,比如图片的旋转裁截拼接,各种渐变处理,文字排列,一开始光是想想就头疼。但没有办法,既然已经需求已经到手上了,那就得把它做好才行,于是便开始被迫营业,无证上岗了。
经过一番查找,找到了一个Go语言图片处理的库,经过调研发现还挺强的,能满足需求,于是决定写点文章,记录一下使用心得,以便日后不时之需。
gg 库的安装和简单使用
使用之前,我们当然得先来安装一下这个库:
go get -u github.com/fogleman/gg
这个库的一个好处是有很多测试代码,可以拿来跑跑看,就知道它大概能实现什么样的效果了。

这是它例子的大概效果图,可以看到,能实现的图形效果还是挺多的。

我们拿其中的一个代码来简单体验一下:
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 的一下,一张黑不溜秋的圆形图就生成了。

关于上面的代码,下面会进行逐一说明。
调整生成图片的大小
dc := gg.NewContext(1000, 1000)
这是先初始化一个 Context 对象,使用库之前都需要先初始化一个 Context 对象,后面的两个 1000,分别对应着最终生成图片的宽度和高度。我们可以修改一下高度为 500 看看效果。
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 语言也可以实现对图片进行很多类型的操作,今天主要介绍了图片的加载、保存、绘制圆形、调整大小和颜色以及裁剪。之后还会进一步介绍其它功能。
我觉得如果不是需要使用并没有熟悉它的必要,但知道有这么个东西,知道它能实现什么样的效果,可以让你手上的牌又多了一张,以后有需要的时候便不至于捉襟见肘了。所以还在等什么,赶紧点赞收藏加关注吧~

【Go语言绘图】gg 库的基本使用的更多相关文章
- 【Go语言绘图】图片添加文字(一)
前一篇讲解了利用gg包来进行图片旋转的操作,这一篇我们来看看怎么在图片上添加文字. 绘制纯色背景 首先,我们先绘制一个纯白色的背景,作为添加文字的背景板. package main import &q ...
- Android 绘图工具库AChartEngine
From: http://www.oschina.net/p/achartengine AChartEngine是为android应用而设计的绘图工具库.目前该库的最新稳定版本是0.7,支持绘制以下类 ...
- C语言常用的库文件(头文件、函数库)
C语言常用的库文件(头文件.函数库) C系统提供了丰富的系统文件,称为库文件.C的库文件分为两类,一类是扩展名为".h"的文件,称为头文件,在前面的包含命令中我们已多次使用过.在& ...
- 13-C语言字符串函数库
目录: 一.C语言字符串函数库 二.用命令行输入参数 回到顶部 一.C语言字符串函数库 1 #include <string.h> 2 字符串复制 strcpy(参数1,参数2); 参数1 ...
- H5新特性——--第三方绘图工具库 echarts(canvas)---SVG绘图
今天学习的内容 3.1:h5新特性---第三方绘图工具库 echarts(canvas) 百度 echarts;d3;two.js;.... 3.2:h5新特性---SVG绘图 3.2:h5新特性-- ...
- nodejs选择JavaScript作为开发语言,是因为一般的开发语言的标准库都是带有IO模块的,并且通常这个 模块是阻塞性的,所以nodejs选择了没有自带IO模块的Javascript
Javascrip本身不带IO功能,nodejs选择JavaScript作为开发语言,是因为一般的开发语言的标准库都是带有IO模块的,并且通常这个 模块是阻塞性的,所以nodejs选择了没有自带IO模 ...
- Tesseract.js 一个几乎能识别出图片中所有语言的JS库
Tesseract.js 一个几乎能识别出图片中所有语言的JS库. 官网:http://tesseract.projectnaptha.com/ git:https://github.com/napt ...
- C语言创建共享库(动态库)步骤
C语言创建共享库(动态库)步骤: 创建sth.c,共享库源文件: //sth.c库源程序 unsigned long long sth(unsigned int x, unsigned int y) ...
- 【Go语言绘图】图片的旋转
在上一篇中,我们了解了gg库的基本使用,包括调整大小.调整圆形参数.设置颜色.保存图片.加载图片和裁剪.这一篇我们来学习一下图片的旋转. 加载图片 首先,我们先来一张黄图. func TestRota ...
随机推荐
- k8s部署之系统初始化(一)
初始化 1.安装依赖包 yum -y install tree lrzsz nmap nc telnet vim wget lsof network-tools bash-completion bas ...
- Learn day7 继承(单、多、菱形)\多态\魔术方法\装饰器\异常
1.继承 1.1 单继承# ### 继承 """ (1) 单继承 (2) 多继承 至少2个类,子类和父类 一个类继承另外一个类,当前类是子类 (衍生类) 被继承的这个类是 ...
- 水题挑战1:NOIP 2013 选择客栈
丽江河边有\(n\) 家很有特色的客栈,客栈按照其位置顺序从 \(1\) 到 \(n\) 编号.每家客栈都按照某一种色调进行装饰(总共 \(k\) 种,用整数 \(0 \sim k-1\) 表示),且 ...
- 【CF1443F】Identify the Operations 题解
原题链接 题意简介 建议去原题看.这题意我表达不清楚. 大概就是给你一个 n 的排列,现在要求你进行 m 次操作. 每次操作,你会在现有的排列中删去一个数,然后选择其左边或右边的一个与之相邻的数加入 ...
- 使用 Iceberg on Kubernetes 打造新一代云原生数据湖
背景 大数据发展至今,按照 Google 2003年发布的<The Google File System>第一篇论文算起,已走过17个年头.可惜的是 Google 当时并没有开源其技术,& ...
- .netcore使用autofac
.netcore3.1使用autofac (.netcore中本身已经实现了IOC容器,其实没有必要替换成autofac.如果非常习惯autofac,替换也是无可厚非的.) 第一步.在项目中引入Aut ...
- .Net Newtonsoft.Json 转json时将枚举转为字符串
1:非列表类型枚举 [JsonConverter(typeof(StringEnumConverter))] public SubjectTypeEnum subject_type { get; se ...
- CEF避坑指南(一)——编译并自制浏览器
CEF即Chromium Embedded Framework,Chrome浏览器嵌入式框架.我们可以从自制浏览器入手,深入学习它.它提供了接口供程序员们把Chrome放到自己的程序中.许多大型公司, ...
- php 获取时间相差的月份和天数
function getMonthAndDay($date1,$date2){ $datestart= date('Y-m-d',strtotime($date1)); if(strtotime($d ...
- SpringBoot中的响应式web应用
目录 简介 Reactive in Spring 注解方式使用WebFlux 编程方式使用webFlux Spring WebFlux的测试 总结 简介 在Spring 5中,Spring MVC引入 ...