最近在研究要如何知道繪製文字時,文字的位置到底為何處
以下的 code 是在 (50, 50) 的位置中繪製一個 綠色的區塊,並在同一位置繪製文字——Hello, golang image
。
package main
import (
"image"
"image/color"
"golang.org/x/image/font"
"golang.org/x/image/font/basicfont"
"golang.org/x/image/math/fixed"
)
func main() {
img := image.NewRGBA(image.Rect(0, 0, 300, 100))
textX, textY := 50, 50
fontFace := basicfont.Face7x13
// 在 (50, 50) 繪製一個 150 ✕ 20 的長方形
for y := textY; y < textY+20; y++ {
for x := textX; x < textX+150; x++ {
img.Set(x, y, color.NRGBA{
R: 0,
G: 0xAF,
B: 0,
A: 0x99,
})
}
}
// 繪製文字
d := &font.Drawer{
Dst: img,
Src: image.NewUniform(color.RGBA{0x4b, 0x11, 0x80, 0xff}),
Face: fontFace,
Dot: fixed.P(textX, textY),
}
d.DrawString("Hello, golang image")
// 輸出圖片的 code (下略)
}
會得到以下圖片
可以很明顯地看出來,文字並不是繪製於 (50, 50) 這個位置
研究一下後,發現 Font.Face 有 GlyphBounds 這個 func,可以取得繪製指定文字的位置
如下:
fontFace := basicfont.Face7x13
bound, _, _ := fontFace.GlyphBounds(rune('A'))
// 這樣就可藉由 bound.Min 和 bound.Max 來取得繪製出來的文字的左上、右下的點了
// (bound.Min.X, bound.Min.Y) 為在 (0, 0) 繪製文字 "A" 時,A 的左上頂點
詳細可參閱 Apple 的這張圖
根據這張圖,假設 Q 的頂點距離 Baseline 為 12px,那 bound.Min.Y (實際上 bound.Min.Y / X 是特殊類型,還要經過 Round() 之類的 func 來轉換成 pixel,但這邊為了敘述方便所以省略)就會是 -12;
同理,若 Q 的尾巴最底端離 Baseline 有 3px,那 bound.Max.Y 會是 3。
根據這結論,如果我要讓字串的繪製於 (50, 50),位移應該要是 (50 - bound.Min.X, 50 -bound.Min.Y)
所以 code 應為:
package main
import (
"bytes"
"encoding/base64"
"fmt"
"image"
"image/color"
"golang.org/x/image/font"
"golang.org/x/image/font/basicfont"
"golang.org/x/image/math/fixed"
)
func main() {
img := image.NewRGBA(image.Rect(0, 0, 300, 100))
textX, textY := 50, 50
fontFace := basicfont.Face7x13
{
for y := textY; y < textY+20; y++ {
for x := textX; x < textX+150; x++ {
img.Set(x, y, color.NRGBA{
R: 0,
G: 0xAF,
B: 0,
A: 0x99,
})
}
}
}
bound, _, _ := fontFace.GlyphBounds(rune('H'))
d := &font.Drawer{
Dst: img,
Src: image.NewUniform(color.RGBA{0x4b, 0x11, 0x80, 0xff}),
Face: fontFace,
Dot: fixed.P(textX-bound.Min.X.Round(), textY-bound.Min.Y.Round()),
}
d.DrawString("Hello, golang image")
// 輸出圖片的 code (下略)
}
輸出結果:
沒有留言:
張貼留言