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 ...
随机推荐
- Ubuntu安装取色软件
sudo apt-get install Gpick
- POJ1019——Number Sequence(大数处理)
Number Sequence DescriptionA single positive integer i is given. Write a program to find the digit l ...
- IE内存泄露与无法回收研究小结
一.内存泄露 之前确实看了很多资料,但这位大哥的话可谓画龙点睛,不是奉承他,一下子就打通了我的任督二脉,请看: trarck 写道 IE下的内存泄露原因就是循环引用,IE的垃圾回收器不能很 ...
- 深入理解Java内存模型(六)——final
与前面介绍的锁和volatile相比较,对final域的读和写更像是普通的变量访问.对于final域,编译器和处理器要遵守两个重排序规则: 在构造函数内对一个final域的写入,与随后把这个被构造对象 ...
- Eclipse 下如何删除一个项目的 SVN 信息
选中项目,右键 - Team - 断开连接 出现如下对话框,根据需要,选择 “删除”或者“不删除”,点击 Yes 即可
- ZOJ Problem Set - 3804 YY's Minions
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5336 比较简单的模拟题,题意也很好理解. #include <iostr ...
- TFSAPI
Team Foundation Server (TFS)工具的亮点之一是管理日常工作项, 工作项如Bug, Task,Task Case等. 使用TFS API编程访问TFS服务器中的工作项, 步骤如 ...
- Effective STL 中文版(大全)
Effective STL 中文版(大全) 作者:winter 候捷说,对于STL,程序员有三个境界,开始是使用STL,然后是理解STL,最后是补充STL.Effective STL是一本非常好的书, ...
- 如何使用LiveSuite debian img格式的镜像文件刷入nand
1. liveSuite启动后 2. 选择固件(就是对应的img文件) 3. 将cubieboard板子的fel按钮按住不要松,然后使用otg接口线插入电脑和cubieboard板子,直到liveSu ...
- UIPikerView
UIPikerView的属性 1. numberOfComponents:返回UIPickerView当前的列数 NSInteger num = _pickerView.numberOfCompo ...