前一节讲的是 绘图到不同输出源,请看地址: 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. Bootstrap的clearfix

    1.div的内容太多会导致后面的div错位 <!DOCTYPE html> <html> <head> <title>自定义占满wgnu</tit ...

  2. android+apimonitor+genymotion

    1. 安装genymotion: http://www.genymotion.net/ 2. 设置使用adb Setting--adb--选择sdk的目录 3. apimonitor https:// ...

  3. WAS集群服务的关闭与启动

    WAS集群服务的关闭与启动 欢迎转载,转载时请务必注明出处(http://blog.csdn.net/huangyanlong),否则作者保留追究版权法律责任. 表述有错误之处,请您留言或邮件(hyl ...

  4. Spring MVC配置DispatcherServlet的url-pattern

    在配置Spring MVC的核心过滤器DispatcherServlet的url-pattern时是有要求的. <servlet> <servlet-name>...</ ...

  5. MyBatis学习总结_11_MyBatis动态Sql语句

    MyBatis中对数据库的操作,有时要带一些条件,因此动态SQL语句非常有必要,下面就主要来讲讲几个常用的动态SQL语句的语法 MyBatis中用于实现动态SQL的元素主要有: if choose(w ...

  6. Android 软键盘弹出时把布局顶上去,控件乱套解决方法

    解决办法:方法一:在你的activity中的oncreate中setContentView之前写上这个代码getWindow().setSoftInputMode(WindowManager.Layo ...

  7. java读写中文文件

    在用Java程序进行读写含中文的txt文件时,经常会出现读出或写入的内容会出现乱码.原因其实很简单,就是系统的编码和程序的编码采用了不同的编码格式.通常,假如自己不修改的话,windows自身采用的编 ...

  8. eclipse运行mapreduce报错Permission denied

    今天用在eclipse-hadoop平台上运行map reduce(word count)出错了,错误信息为 org.apache.hadoop.security.AccessControlExcep ...

  9. excel跨表数据链接

    按=,然后选择第二个页签下某个数据. 去掉$号,就可以下拉数据

  10. 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). ...