前言
上一篇介绍了生成RGBA对象,并生成一张png图像写入硬盘中。本文主要介绍如何向RGBA对象绘制文字。
代码
package main
import (
"image"
"os"
"fmt"
"bufio"
"image/png"
"github.com/golang/freetype"
"io/ioutil"
"log"
"image/draw"
)
func GetContext(s string) *freetype.Context {
fontBytes,err := ioutil.ReadFile(s)
if err != nil{
log.Println("ReadFile",s,err)
return nil
}
f,err := freetype.ParseFont(fontBytes)
if err != nil{
log.Println("ParseFont",err)
return nil
}
c := freetype.NewContext()
c.SetFont(f)
c.SetDPI(72)
c.SetFont(f)
c.SetFontSize(26)
return c
}
func main(){
background := image.NewRGBA(image.Rect(0,0,500,500))
draw.Draw(background,background.Bounds(),image.White,image.ZP,draw.Src)
context := GetContext("font.ttf")
context.SetClip(background.Bounds())
context.SetDst(background)
context.SetSrc(image.Black)
pt := freetype.Pt(10,10 + int(context.PointToFixed(26)>>6))
_ , err := context.DrawString("你好go",pt);
if err !=nil{
fmt.Println(err)
os.Exit(1)
}
outFile,err := os.Create("p1.png")
if err != nil{
fmt.Println(err)
os.Exit(-1)
}
defer outFile.Close()
buff := bufio.NewWriter(outFile)
err = png.Encode(buff,background)
if err != nil{
fmt.Println(err)
os.Exit(-1)
}
err = buff.Flush()
if err != nil{
fmt.Println(err)
os.Exit(-1)
}
fmt.Println("Save to 1.png")
}
画图接口
接口在image/draw包,dst为目标图像,r为在目标图像绘制位置。src为源图像,sp为源图像的起始点,op可以理解为绘制操作的类型。
Draw函数使用nil的mask参数调用DrawMask函数。
//image/draw
func Draw(dst Image, r image.Rectangle, src image.Image, sp image.Point, op Op) {
DrawMask(dst, r, src, sp, nil, image.Point{}, op)
}
对齐目标图像dst的矩形r左上角、源图像src的sp点、遮罩mask的mp点,根据op修改dst的r矩形区域内的内容,mask如果为nil则视为完全透明。
//image/draw
func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mask image.Image, mp image.Point, op Op)
下面这行代码成功地将background图像初始化为的白色。
draw.Draw(background,background.Bounds(),image.White,image.ZP,draw.Src)
读取文件
现在需要读取字体格式文件,将加载字体结构。 用io/ioutil包,读取文件.
//io/ioutil
func ReadFile(filename string) ([]byte, error)
加载字体格式
ParseFont加载.ttf字体格式文件的内容,并返回truetype.Font的字体结构,这里不过多深究字体格式
//github.com/golang/freetype
func ParseFont(b []byte) (*truetype.Font, error)
定义字体样式
//github.com/golang/freetype
func NewContext() *Context
// 设置屏幕分辨率的DPI
func (c *Context) SetDPI(dpi float64)
// 设置字体样式,为ParseFont的返回值
func (c *Context) SetFont(f *truetype.Font)
// 设置字体占用像素
func (c *Context) SetFontSize(fontSize float64)
// SetHinting sets the hinting policy.
func (c *Context) SetHinting(hinting font.Hinting)
// 设置要绘制的目标图像
func (c *Context) SetDst(dst draw.Image) {
c.dst = dst
}
// 猜测应该是设置采样图像
func (c *Context) SetSrc(src image.Image)
// 设置绘制范围
func (c *Context) SetClip(clip image.Rectangle)
定义绘制位置
//返回一个屏幕坐标定义好的位置,该位置为文字左上角
func Pt(x, y int) fixed.Point26_6
func (c *Context) PointToFixed(x float64) fixed.Int26_6 {
return fixed.Int26_6(x * float64(c.dpi) * (64.0 / 72.0))
}
注意x,y指定文字左上角的像素坐标,通常我们是希望指定文字左下角的像素坐标。 例如我们希望在(10,10)位置写方案,若直接调用传(10,10)的点,结果如下
写文字到图像
在指定位置写指定文字
func (c *Context) DrawString(s string, p fixed.Point26_6) (fixed.Point26_6, error)