登录 用户中心() [退出] 后台管理 注册
   
您的位置: 首页 >> SoftHub关联区 >> 主题: Golang 绘图基础 -绘制简单图形[zt]     [回主站]     [分站链接]
Golang 绘图基础 -绘制简单图形[zt]
clq
浏览(259) - 2020-09-05 15:56:55 发表 编辑

关键字:

Golang 绘图基础 -绘制简单图形[zt]

值得一提的是原作者身为 csdn 的人却在 cnblog 写日志 ...

https://www.cnblogs.com/ghj1976/p/3441536.html

----------------------------------------------------------------

Golang 绘图基础 -绘制简单图形
Posted on 2013-11-25 15:02 蝈蝈俊 阅读(10029) 评论(0) 编辑 收藏

前一节讲的是 绘图到不同输出源,请看地址: http://www.cnblogs.com/ghj1976/p/3440856.html

上一节的例子效果是通过设置每一个点的的RGBA属性来实现的,这是最基础的方式,通过这种方式我们可以绘制任意形状的图形。
1、设置点的颜色一个简单例子:

效果如下:

123

代码如下,跟最初我们的代码唯一不同的是设置点颜色时,多了一个条件判断语句: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

这个算法画的线简单可以用下面图来标示:

800px-Bresenham.svg

下面演示代码画出来的效果图如下:

注意,为了便于看到效果, 图的左右都画了一条竖线,斜线是按照上面算法画出来的。

250

相关代码如下:
这里的代码借鉴了下面的代码。
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、特殊图形

这次绘制出来的图形效果如下:

1234



相关代码如下:
这里的代码借鉴了下面的代码:
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
分类: Go语言



总数:0 页次:1/0 首页 尾页  
总数:0 页次:1/0 首页 尾页  


所在合集/目录



发表评论:
文本/html模式切换 插入图片 文本/html模式切换


附件:



NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.

Copyright © 2005-2020 clq, All Rights Reserved
版权所有
桂ICP备15002303号-1