Golang 绘图基础 -绘制简单图形
2013-11-25 15:02
465 查看
前一节讲的是 绘图到不同输出源,请看地址: /article/4864658.html
上一节的例子效果是通过设置每一个点的的RGBA属性来实现的,这是最基础的方式,通过这种方式我们可以绘制任意形状的图形。
代码如下,跟最初我们的代码唯一不同的是设置点颜色时,多了一个条件判断语句:if x%8 == 0 ,代码如下,这种情况下,其实我们通过算法简单的实现了画垂直线的效果:
[/code]
比如下面一个函数就是简单的画水平线的代码函数。
[/code]
http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
这个算法画的线简单可以用下面图来标示:
下面演示代码画出来的效果图如下:
注意,为了便于看到效果, 图的左右都画了一条竖线,斜线是按照上面算法画出来的。
相关代码如下:
这里的代码借鉴了下面的代码。
https://github.com/akavel/polyclip-go/blob/9b07bdd6e0a784f7e5d9321bff03425ab3a98beb/polyutil/draw.go
上一节的例子效果是通过设置每一个点的的RGBA属性来实现的,这是最基础的方式,通过这种方式我们可以绘制任意形状的图形。
1、设置点的颜色一个简单例子:
效果如下:代码如下,跟最初我们的代码唯一不同的是设置点颜色时,多了一个条件判断语句:if x%8 == 0 ,代码如下,这种情况下,其实我们通过算法简单的实现了画垂直线的效果:
[code] package main
import (
"fmt"
"image"
"image/color"
"image/png"
"log"
"os"
)
func main() {
const (
dx = 300
dy = 500
)
// 需要保存的文件
imgcounter := 123
imgfile, _ := os.Create(fmt.Sprintf("%03d.png", imgcounter))
defer imgfile.Close()
// 新建一个 指定大小的 RGBA位图
img := image.NewNRGBA(image.Rect(0, 0, dx, dy))
for y := 0; y < dy; y++ {
for x := 0; x < dx; x++ {
if x%8 == 0 {
// 设置某个点的颜色,依次是 RGBA
img.Set(x, y, color.RGBA{uint8(x % 256), uint8(y % 256), 0, 255})
}
}
}
// 以PNG格式保存文件
err := png.Encode(imgfile, img)
if err != nil {
log.Fatal(err)
}
}
[/code]
比如下面一个函数就是简单的画水平线的代码函数。
[code] // 画 水平线
func (img *Image) drawHorizLine(color color.Color, fromX, toX, y int) {
// 遍历画每个点
for x := fromX; x <= toX; x++ {
img.Set(x, y, color)
}
}
[/code]
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
[code] package main
import (
"fmt"
"image"
"image/color"
"image/png"
"log"
"os"
)
// Putpixel describes a function expected to draw a point on a bitmap at (x, y) coordinates.
type Putpixel func(x, y int)
// 求绝对值
func abs(x int) int {
if x >= 0 {
return x
}
return -x
}
// Bresenham's algorithm, http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm[/code]// https://github.com/akavel/polyclip-go/blob/9b07bdd6e0a784f7e5d9321bff03425ab3a98beb/polyutil/draw.go[/code]// TODO: handle int overflow etc.func drawline(x0, y0, x1, y1 int, brush Putpixel) {dx := abs(x1 - x0)dy := abs(y1 - y0)sx, sy := 1, 1if x0 >= x1 {sx = -1}if y0 >= y1 {sy = -1}err := dx - dyfor {brush(x0, y0)if x0 == x1 && y0 == y1 {return}e2 := err * 2if e2 > -dy {err -= dyx0 += sx}if e2 < dx {err += dxy0 += sy}}}func main() {const (dx = 300dy = 500)// 需要保存的文件// 新建一个 指定大小的 RGBA位图img := image.NewNRGBA(image.Rect(0, 0, dx, dy))drawline(5, 5, dx-8, dy-10, func(x, y int) {img.Set(x, y, color.RGBA{uint8(x), uint8(y), 0, 255})})// 左右都画一条竖线for i := 0; i < dy; i++ {img.Set(0, i, color.Black)img.Set(dx-1, i, color.Black)}imgcounter := 250imgfile, _ := os.Create(fmt.Sprintf("%03d.png", imgcounter))defer imgfile.Close()// 以PNG格式保存文件err := png.Encode(imgfile, img)if err != nil {log.Fatal(err)}}
[/code]
3、特殊图形
这次绘制出来的图形效果如下:
相关代码如下:
这里的代码借鉴了下面的代码:
https://github.com/xMachinae/pallinda13/blob/master/uppg2.go[code] package mainimport ("fmt""image""image/png""log""os")func Pic(dx, dy int) [][]uint8 {pic := make([][]uint8, dx)for i := range pic {pic[i] = make([]uint8, dy)for j := range pic[i] {pic[i][j] = uint8(i * j)}}return pic}func main() {Show(Pic)}func Show(f func(int, int) [][]uint8) {const (dx = 256dy = 256)data := f(dx, dy) // 图片坐标点的颜色二维数组。m := image.NewNRGBA(image.Rect(0, 0, dx, dy))for y := 0; y < dy; y++ {for x := 0; x < dx; x++ {v := data[y][x]i := y*m.Stride + x*4m.Pix[i] = vm.Pix[i+1] = vm.Pix[i+2] = 255m.Pix[i+3] = 255}}ShowImage(m)}func ShowImage(m image.Image) {// 需要保存的文件imgcounter := 1234imgfile, _ := os.Create(fmt.Sprintf("%03d.png", imgcounter))defer imgfile.Close()// 以PNG格式保存文件err := png.Encode(imgfile, m)if err != nil {log.Fatal(err)}}
[/code]
更复杂的算法
比如下面代码实现了图片简单的上下左右翻转的功能。
图片旋转的算法
https://github.com/mpl/goexif/blob/a588a5577cedfda71e3645f8137c38495f308f6c/exif/rotate_test.go
相关文章推荐
- Qt 2D绘图(一)绘制简单图形
- HTML5绘图基础_07_绘制第二个图形
- 自定义View之绘图篇(一):基础图形的绘制
- JAVA基础8.1——绘图基础(1)绘制图形
- IOS之Quartz2D绘图1.简单几何图形绘制
- HTML5绘图基础_08_绘制多个图形(七巧板)
- 零基础HTML5游戏制作教程 第2章 简单图形的绘制
- [Qt教程] 第11篇 2D绘图(一)绘制简单图形
- 十一、Qt 2D绘图(一)绘制简单图形
- flash 绘图API:绘制基础的图形
- flash 绘图API:绘制基础的图形
- canvas基础——绘制简单的图形
- 利用Microsoft VC++6.0 的MFC 的绘图工具实现简单图形的绘制
- VS2010 使用TeeChart绘图控件 - 之二 - 绘制图形(折线图,柱状图)
- C# 实现完整功能的截图控件(1)-实现绘图工具栏控件 控件实现了截图、绘制矩形、圆形、箭头、线条、文字,还需要可以撤销绘制步骤、保存图形等功能,基本实现了跟QQ2008截图一样的功能,还可以更
- 【Visual C++】游戏开发笔记之四――游戏画面绘图(一)基本图形绘制
- VS2010 使用TeeChart绘图控件 - 之二 - 绘制图形(折线图,柱状图)
- 简单图形绘制
- 原生js实现Canvas实现拖拽式绘图,支持画笔、线条、箭头、三角形和圆形等等图形绘制功能,有实例Demo
- WTL下实现的PPC绘制图形的简单范例