前一节讲的是 绘图到不同输出源,请看地址: 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 绘图基础 -绘制简单图形的更多相关文章

  1. 学习笔记:HTML5 Canvas绘制简单图形

    HTML5 Canvas绘制简单图形 1.添加Canvas标签,添加id供js操作. <canvas id="mycanvas" height="700" ...

  2. Java入门:绘制简单图形

    在上一节,我们学习了如何使用swing和awt工具创建一个空的窗口,本节学习如何绘制简单图形. 基本绘图介绍 Java中绘制基本图形,可以使用Java类库中的Graphics类,此类位于java.aw ...

  3. CSS绘制简单图形

    究竟该用字体图标.图片图标.还是CSS画一个图标?我也不知道.各有千秋吧.本文将介绍如何用css绘制简单的图形,所有测试在chrome58.0完成,如果你不能得到正确结果请到caniuse查一查看看是 ...

  4. Windows控制台下绘制简单图形

    最近接触到一个很有意思的问题,如何在Windows控制台下画图,翻遍了C的头文件也没找到画图的函数,好吧,那就用Windows提供的API函数吧,看来想移植是没戏了.先画一个简单的图,类似心电图那种吧 ...

  5. 利用 turtle库绘制简单图形

    turtle库是python的基础绘图库,这个库被介绍为一个最常用的用来介绍编程知识的方法库,其主要是用于程序设计入门,是标准库之一,利用turtle可以制作很多复杂的绘图. turtle名称含义为“ ...

  6. iOS:quartz2D绘图(绘制渐变图形)

    quartzD可以用来绘制渐变图形,即图形向外或向内发散,会变得越来越模糊. 渐变分为线性渐变和径向渐变,所谓线性渐变,就是图形以线的方式发散,发散后一般呈现出矩形的样子:而径向渐变,就是以半径的大小 ...

  7. shape-自绘制简单图形

    shape 可以绘制简单的图形,颜色等.它主要就是应用于selector 的一些状态. 本文内容参考自http://www.cnblogs.com/cyanfei/archive/2012/07/27 ...

  8. 在高德地图上用svg.js绘制简单图形

    这段时间做的一个项目,需要在地图上绘制简单的图形.在学习高德地图JS API的过程中,发现高德地图提供的点.线等API并不能满足我的需求,还好它开放了自定义图层CustomLayer,官方说自定义图层 ...

  9. 利用Microsoft VC++6.0 的MFC 的绘图工具实现简单图形的绘制

          MFC运算功能强大,拥有完备的绘图功能.       在Windows平台上,应用程序的图形设备接口(graphics device interface,GDI)被抽象为设备上下文(Dev ...

随机推荐

  1. Ubuntu安装取色软件

    sudo apt-get install Gpick

  2. POJ1019——Number Sequence(大数处理)

    Number Sequence DescriptionA single positive integer i is given. Write a program to find the digit l ...

  3. IE内存泄露与无法回收研究小结

    一.内存泄露    之前确实看了很多资料,但这位大哥的话可谓画龙点睛,不是奉承他,一下子就打通了我的任督二脉,请看: trarck 写道    IE下的内存泄露原因就是循环引用,IE的垃圾回收器不能很 ...

  4. 深入理解Java内存模型(六)——final

    与前面介绍的锁和volatile相比较,对final域的读和写更像是普通的变量访问.对于final域,编译器和处理器要遵守两个重排序规则: 在构造函数内对一个final域的写入,与随后把这个被构造对象 ...

  5. Eclipse 下如何删除一个项目的 SVN 信息

    选中项目,右键 - Team - 断开连接 出现如下对话框,根据需要,选择 “删除”或者“不删除”,点击 Yes 即可

  6. ZOJ Problem Set - 3804 YY's Minions

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5336 比较简单的模拟题,题意也很好理解. #include <iostr ...

  7. TFSAPI

    Team Foundation Server (TFS)工具的亮点之一是管理日常工作项, 工作项如Bug, Task,Task Case等. 使用TFS API编程访问TFS服务器中的工作项, 步骤如 ...

  8. Effective STL 中文版(大全)

    Effective STL 中文版(大全) 作者:winter 候捷说,对于STL,程序员有三个境界,开始是使用STL,然后是理解STL,最后是补充STL.Effective STL是一本非常好的书, ...

  9. 如何使用LiveSuite debian img格式的镜像文件刷入nand

    1. liveSuite启动后 2. 选择固件(就是对应的img文件) 3. 将cubieboard板子的fel按钮按住不要松,然后使用otg接口线插入电脑和cubieboard板子,直到liveSu ...

  10. UIPikerView

    UIPikerView的属性 1.   numberOfComponents:返回UIPickerView当前的列数 NSInteger num = _pickerView.numberOfCompo ...