Golang 绘图基础 -绘制简单图形
前一节讲的是 绘图到不同输出源,请看地址: http://www.cnblogs.com/ghj1976/p/3440856.html
上一节的例子效果是通过设置每一个点的的RGBA属性来实现的,这是最基础的方式,通过这种方式我们可以绘制任意形状的图形。
1、设置点的颜色一个简单例子:
效果如下:
代码如下,跟最初我们的代码唯一不同的是设置点颜色时,多了一个条件判断语句:if x%8 == 0 ,代码如下,这种情况下,其实我们通过算法简单的实现了画垂直线的效果:
1: package main
2:
3: import (
4: "fmt"
5: "image"
6: "image/color"
7: "image/png"
8: "log"
9: "os"
10: )
11:
12: func main() {
13: const (
14: dx = 300
15: dy = 500
16: )
17:
18: // 需要保存的文件
19: imgcounter := 123
20: imgfile, _ := os.Create(fmt.Sprintf("%03d.png", imgcounter))
21: defer imgfile.Close()
22:
23: // 新建一个 指定大小的 RGBA位图
24: img := image.NewNRGBA(image.Rect(0, 0, dx, dy))
25:
26: for y := 0; y < dy; y++ {
27: for x := 0; x < dx; x++ {
28:
29: if x%8 == 0 {
30: // 设置某个点的颜色,依次是 RGBA
31: img.Set(x, y, color.RGBA{uint8(x % 256), uint8(y % 256), 0, 255})
32: }
33: }
34: }
35:
36: // 以PNG格式保存文件
37: err := png.Encode(imgfile, img)
38: if err != nil {
39: log.Fatal(err)
40: }
41:
42: }
比如下面一个函数就是简单的画水平线的代码函数。
1: // 画 水平线
2: func (img *Image) drawHorizLine(color color.Color, fromX, toX, y int) {
3: // 遍历画每个点
4: for x := fromX; x <= toX; x++ {
5: img.Set(x, y, color)
6: }
7: }
2、划线
Golang 官方库没有提供划线的库,不过既然有了画点的方法,我们就可以根据一套算法画出点,下面的效果和代码是按照 Bresenham's line algorithm 算法画的线。
http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
这个算法画的线简单可以用下面图来标示:
下面演示代码画出来的效果图如下:
注意,为了便于看到效果, 图的左右都画了一条竖线,斜线是按照上面算法画出来的。
相关代码如下:
这里的代码借鉴了下面的代码。
https://github.com/akavel/polyclip-go/blob/9b07bdd6e0a784f7e5d9321bff03425ab3a98beb/polyutil/draw.go
1: package main
2:
3: import (
4: "fmt"
5: "image"
6: "image/color"
7: "image/png"
8: "log"
9: "os"
10: )
11:
12: // Putpixel describes a function expected to draw a point on a bitmap at (x, y) coordinates.
13: type Putpixel func(x, y int)
14:
15: // 求绝对值
16: func abs(x int) int {
17: if x >= 0 {
18: return x
19: }
20: return -x
21: }
22:
23: // Bresenham's algorithm, http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
24: // https://github.com/akavel/polyclip-go/blob/9b07bdd6e0a784f7e5d9321bff03425ab3a98beb/polyutil/draw.go
25: // TODO: handle int overflow etc.
26: func drawline(x0, y0, x1, y1 int, brush Putpixel) {
27: dx := abs(x1 - x0)
28: dy := abs(y1 - y0)
29: sx, sy := 1, 1
30: if x0 >= x1 {
31: sx = -1
32: }
33: if y0 >= y1 {
34: sy = -1
35: }
36: err := dx - dy
37:
38: for {
39: brush(x0, y0)
40: if x0 == x1 && y0 == y1 {
41: return
42: }
43: e2 := err * 2
44: if e2 > -dy {
45: err -= dy
46: x0 += sx
47: }
48: if e2 < dx {
49: err += dx
50: y0 += sy
51: }
52: }
53: }
54:
55: func main() {
56:
57: const (
58: dx = 300
59: dy = 500
60: )
61:
62: // 需要保存的文件
63:
64: // 新建一个 指定大小的 RGBA位图
65: img := image.NewNRGBA(image.Rect(0, 0, dx, dy))
66:
67: drawline(5, 5, dx-8, dy-10, func(x, y int) {
68: img.Set(x, y, color.RGBA{uint8(x), uint8(y), 0, 255})
69: })
70:
71: // 左右都画一条竖线
72: for i := 0; i < dy; i++ {
73: img.Set(0, i, color.Black)
74: img.Set(dx-1, i, color.Black)
75: }
76:
77: imgcounter := 250
78: imgfile, _ := os.Create(fmt.Sprintf("%03d.png", imgcounter))
79: defer imgfile.Close()
80:
81: // 以PNG格式保存文件
82: err := png.Encode(imgfile, img)
83: if err != nil {
84: log.Fatal(err)
85: }
86: }
3、特殊图形
这次绘制出来的图形效果如下:
相关代码如下:
这里的代码借鉴了下面的代码:
https://github.com/xMachinae/pallinda13/blob/master/uppg2.go
1: package main
2:
3: import (
4: "fmt"
5: "image"
6: "image/png"
7: "log"
8: "os"
9: )
10:
11: func Pic(dx, dy int) [][]uint8 {
12: pic := make([][]uint8, dx)
13: for i := range pic {
14: pic[i] = make([]uint8, dy)
15: for j := range pic[i] {
16: pic[i][j] = uint8(i * j)
17: }
18: }
19: return pic
20: }
21:
22: func main() {
23: Show(Pic)
24: }
25:
26: func Show(f func(int, int) [][]uint8) {
27: const (
28: dx = 256
29: dy = 256
30: )
31: data := f(dx, dy) // 图片坐标点的颜色二维数组。
32: m := image.NewNRGBA(image.Rect(0, 0, dx, dy))
33: for y := 0; y < dy; y++ {
34: for x := 0; x < dx; x++ {
35: v := data[y][x]
36: i := y*m.Stride + x*4
37: m.Pix[i] = v
38: m.Pix[i+1] = v
39: m.Pix[i+2] = 255
40: m.Pix[i+3] = 255
41: }
42: }
43: ShowImage(m)
44: }
45:
46: func ShowImage(m image.Image) {
47:
48: // 需要保存的文件
49: imgcounter := 1234
50: imgfile, _ := os.Create(fmt.Sprintf("%03d.png", imgcounter))
51: defer imgfile.Close()
52:
53: // 以PNG格式保存文件
54: err := png.Encode(imgfile, m)
55: if err != nil {
56: log.Fatal(err)
57: }
58:
59: }
更复杂的算法
比如下面代码实现了图片简单的上下左右翻转的功能。
图片旋转的算法
https://github.com/mpl/goexif/blob/a588a5577cedfda71e3645f8137c38495f308f6c/exif/rotate_test.go
Golang 绘图基础 -绘制简单图形的更多相关文章
- 学习笔记:HTML5 Canvas绘制简单图形
HTML5 Canvas绘制简单图形 1.添加Canvas标签,添加id供js操作. <canvas id="mycanvas" height="700" ...
- Java入门:绘制简单图形
在上一节,我们学习了如何使用swing和awt工具创建一个空的窗口,本节学习如何绘制简单图形. 基本绘图介绍 Java中绘制基本图形,可以使用Java类库中的Graphics类,此类位于java.aw ...
- CSS绘制简单图形
究竟该用字体图标.图片图标.还是CSS画一个图标?我也不知道.各有千秋吧.本文将介绍如何用css绘制简单的图形,所有测试在chrome58.0完成,如果你不能得到正确结果请到caniuse查一查看看是 ...
- Windows控制台下绘制简单图形
最近接触到一个很有意思的问题,如何在Windows控制台下画图,翻遍了C的头文件也没找到画图的函数,好吧,那就用Windows提供的API函数吧,看来想移植是没戏了.先画一个简单的图,类似心电图那种吧 ...
- 利用 turtle库绘制简单图形
turtle库是python的基础绘图库,这个库被介绍为一个最常用的用来介绍编程知识的方法库,其主要是用于程序设计入门,是标准库之一,利用turtle可以制作很多复杂的绘图. turtle名称含义为“ ...
- iOS:quartz2D绘图(绘制渐变图形)
quartzD可以用来绘制渐变图形,即图形向外或向内发散,会变得越来越模糊. 渐变分为线性渐变和径向渐变,所谓线性渐变,就是图形以线的方式发散,发散后一般呈现出矩形的样子:而径向渐变,就是以半径的大小 ...
- shape-自绘制简单图形
shape 可以绘制简单的图形,颜色等.它主要就是应用于selector 的一些状态. 本文内容参考自http://www.cnblogs.com/cyanfei/archive/2012/07/27 ...
- 在高德地图上用svg.js绘制简单图形
这段时间做的一个项目,需要在地图上绘制简单的图形.在学习高德地图JS API的过程中,发现高德地图提供的点.线等API并不能满足我的需求,还好它开放了自定义图层CustomLayer,官方说自定义图层 ...
- 利用Microsoft VC++6.0 的MFC 的绘图工具实现简单图形的绘制
MFC运算功能强大,拥有完备的绘图功能. 在Windows平台上,应用程序的图形设备接口(graphics device interface,GDI)被抽象为设备上下文(Dev ...
随机推荐
- Bootstrap的clearfix
1.div的内容太多会导致后面的div错位 <!DOCTYPE html> <html> <head> <title>自定义占满wgnu</tit ...
- android+apimonitor+genymotion
1. 安装genymotion: http://www.genymotion.net/ 2. 设置使用adb Setting--adb--选择sdk的目录 3. apimonitor https:// ...
- WAS集群服务的关闭与启动
WAS集群服务的关闭与启动 欢迎转载,转载时请务必注明出处(http://blog.csdn.net/huangyanlong),否则作者保留追究版权法律责任. 表述有错误之处,请您留言或邮件(hyl ...
- Spring MVC配置DispatcherServlet的url-pattern
在配置Spring MVC的核心过滤器DispatcherServlet的url-pattern时是有要求的. <servlet> <servlet-name>...</ ...
- MyBatis学习总结_11_MyBatis动态Sql语句
MyBatis中对数据库的操作,有时要带一些条件,因此动态SQL语句非常有必要,下面就主要来讲讲几个常用的动态SQL语句的语法 MyBatis中用于实现动态SQL的元素主要有: if choose(w ...
- Android 软键盘弹出时把布局顶上去,控件乱套解决方法
解决办法:方法一:在你的activity中的oncreate中setContentView之前写上这个代码getWindow().setSoftInputMode(WindowManager.Layo ...
- java读写中文文件
在用Java程序进行读写含中文的txt文件时,经常会出现读出或写入的内容会出现乱码.原因其实很简单,就是系统的编码和程序的编码采用了不同的编码格式.通常,假如自己不修改的话,windows自身采用的编 ...
- eclipse运行mapreduce报错Permission denied
今天用在eclipse-hadoop平台上运行map reduce(word count)出错了,错误信息为 org.apache.hadoop.security.AccessControlExcep ...
- excel跨表数据链接
按=,然后选择第二个页签下某个数据. 去掉$号,就可以下拉数据
- poj - 2386 Lake Counting && hdoj -1241Oil Deposits (简单dfs)
http://poj.org/problem?id=2386 http://acm.hdu.edu.cn/showproblem.php?pid=1241 求有多少个连通子图.复杂度都是O(n*m). ...