最近一直在鼓捣怎样用golang画图(不想用cgo来封装c库),终于找到了xgb和freetype-go。
xgb可以用来创建窗口,freetype-go中的raster库可以用来画图。
下面我用它们写了一个简单的程序,它在窗口中画了个90度的扇形
package main
import (
"code.google.com/p/freetype-go/freetype/raster"
"fmt"
"github.com/BurntSushi/xgbutil"
"github.com/BurntSushi/xgbutil/xevent"
"github.com/BurntSushi/xgbutil/xgraphics"
"github.com/BurntSushi/xgbutil/xwindow"
"image"
"image/color"
"image/png"
"os"
)
func main() {
// width and height of the window to be created
w, h := 400, 400
// xu communicates with X server
xu, err := xgbutil.NewConn()
if err != nil {
fmt.Println(err)
return
}
// just create a id for the window
xwin, err := xwindow.Generate(xu)
if err != nil {
fmt.Println(err)
return
}
// now, create the window
err = xwin.CreateChecked(
xu.RootWin(), // parent window
0, 0, w, h, // window size
0) // related to event, not considered here
if err != nil {
fmt.Println(err)
return
}
// now we can see the window on the screen
xwin.Map()
// 'rstr' calculates the data needed to draw
// 'painter' draw with the data on 'canvas'
canvas := image.NewRGBA(image.Rect(0, 0, w, h))
rstr := raster.NewRasterizer(w, h)
painter := raster.NewRGBAPainter(canvas)
painter.SetColor(color.RGBA{0xff, 0xff, 0x00, 0xff})
// specify the start point (100, 100)
// why shift by 8?
// raster.Point has 2 memembers X and Y, they are both of type raster.Fix32
// raster.Fix32 is fixed point number, the high 24 bits is the integral part
// for example, a raster.Fix32 number 1 in fact is 1/256
a := raster.Point{100 << 8, 100 << 8}
rstr.Start(a)
// draw a straight line from the start point
b := raster.Point{200 << 8, 100 << 8}
rstr.Add1(b)
// draw a bezier curve, points b, c, d are the control points
c := raster.Point{200 << 8, 200 << 8}
d := raster.Point{100 << 8, 200 << 8}
rstr.Add2(c, d)
rstr.Add1(a)
// now, draw the shape on 'canvas'
rstr.Rasterize(painter)
// 'canvas' is of type *image.RGBA,
// but the window need xgraphics.Image to show, so we convert it
ximg := xgraphics.NewConvert(xu, canvas)
// I want 'ximg' to show on 'xwin'
ximg.XSurfaceSet(xwin.Id)
// now show it
ximg.XDraw()
ximg.XPaint(xwin.Id)
// save the image to png
fd, err := os.Create("blog.png")
if err != nil {
fmt.Println(err)
return
}
err = png.Encode(fd, canvas)
if err != nil {
fmt.Println(err)
}
// listen on the events such as keypress, mousepress etc.
xevent.Main(xu)
}
[1]: http:///home/shikuijie/blog.png
更多评论