前一节讲的是 绘图到不同输出源,请看地址: 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. 297. Serialize and Deserialize Binary Tree

    题目: Serialization is the process of converting a data structure or object into a sequence of bits so ...

  2. MSBuild和Jenkins搭建持续集成环境

    http://www.2cto.com/os/201409/334323.html http://my.oschina.net/anxuyong/blog/353897 http://www.cnbl ...

  3. SPOJ 274 Johnny and the Watermelon Plantation(TLE)

    O(n^3)的时间复杂度,改了半天交了二三十遍,TLE到死,实在没办法了…… 跪求指点!!! #include <cstdio> #include <cstdlib> #inc ...

  4. PHP的面向对象编程

    面向对象编程的概念: 不同的作者之间说法可能不一样,但是一个OOP语言必须有以下几方面: 抽象数据类型和信息封装 继承 多态 在PHP中是通过类来完成封装的: <?php class Somet ...

  5. 操刀 requirejs,自己动手写一个

    前沿 写在文章的最前面 这篇文章讲的是,我怎么去写一个 requirejs . 去 github 上fork一下,顺便star~ requirejs,众所周知,是一个非常出名的js模块化工具,可以让你 ...

  6. flex 4 布局样式

    Flex 4 样式与布局 第一篇 Flex 4 与自定义布局(Layout) Flex 4/Spark组件架构的新功能之一是可以定制一个容器的布局而不必改变容器本身.您需要做的就是定义一个自定义布局. ...

  7. ffmpeg mp4转yuv

    mp4转yuv ffmpeg -i test.mp4 test.yuv 播放yuv ffplay.exe -f rawvideo -video_size 1280x720 -i test.yuv

  8. 【分享】IT产业中的三大定理(二) —— 安迪&比尔定理 (Andy and Bill's Law)

    摩尔定理给所有的计算机消费者带来一个希望,如果我今天嫌计算机太贵买不起,那么我等十八个月就可以用一半的价钱来买.要真是这样简单的话,计算机的销售量就上不去了.需要买计算机的人会多等几个月,已经有计算机 ...

  9. 关于c#字典key不存在的测试

    之前一直隐约记得没有创建key会报异常,测试了下. 测试结果: 写入值,如果不存在key,会自动创建. 取值,如果不存在key,会报异常. 一般用c#提供了尝试取值方法,不过有out参数,考虑写扩展 ...

  10. Map和hash_map

    map和hash_map 今天在写拼流的程序时碰到一个问题,要根据流的四元组的结构信息映射到该流的数据.也就是我在网络数据包拼接的过程中,要根据包的地址和端口信息,对应到其对应的一个流的数据上去,把端 ...