Given image.RGBA
, coordinates, and a line of text, how do I add a simple label with any plain fixed font? E.g. Face7x13
from font/basicfont
.
package main
import (
"image"
"image/color"
"image/png"
"os"
)
func main() {
img := image.NewRGBA(image.Rect(0, 0, 320, 240))
x, y := 100, 100
addLabel(img, x, y, "Test123")
png.Encode(os.Stdout, img)
}
func addLabel(img *image.RGBA, x, y int, label string) {
col := color.Black
// now what?
}
Alignment doesn't really matter, but best if I could write the label above a line which starts at the coordinates.
And I would like to avoid external loadable dependencies like fonts.
The golang.org/x/image/font
package just defines interfaces for font faces and drawing text on images.
You may use the Go implementation of Freetype font rasterizer: github.com/golang/freetype
.
The key type is freetype.Context
, it has all the methods you need.
For a complete example, check out this file: example/freetype/main.go
. This example loads a font file, creates and configures freetype.Context
, draws text on image and saves the result image to file.
Let's assume you already have the font file loaded, and a c
context configured (see the example how to do that). Then your addLabel()
function could look like this:
func addLabel(img *image.RGBA, x, y int, label string) {
c.SetDst(img)
size := 12.0 // font size in pixels
pt := freetype.Pt(x, y+int(c.PointToFixed(size)>>6))
if _, err := c.DrawString(label, pt); err != nil {
// handle error
}
}
If you don't want to hassle with the freetype
package and external font files, the font/basicfont
package contains a basic font named Face7x13
whose graphical data is entirely self-contained. This is how you could use that:
import (
"golang.org/x/image/font"
"golang.org/x/image/font/basicfont"
"golang.org/x/image/math/fixed"
"image"
"image/color"
)
func addLabel(img *image.RGBA, x, y int, label string) {
col := color.RGBA{200, 100, 0, 255}
point := fixed.Point26_6{fixed.Int26_6(x * 64), fixed.Int26_6(y * 64)}
d := &font.Drawer{
Dst: img,
Src: image.NewUniform(col),
Face: basicfont.Face7x13,
Dot: point,
}
d.DrawString(label)
}
This is how this addLabel()
function can be used: the code below creates a new image, draws the "Hello Go"
text on it and saves it in a file named hello-go.png
:
func main() {
img := image.NewRGBA(image.Rect(0, 0, 300, 100))
addLabel(img, 20, 30, "Hello Go")
f, err := os.Create("hello-go.png")
if err != nil {
panic(err)
}
defer f.Close()
if err := png.Encode(f, img); err != nil {
panic(err)
}
}
Note the above code also requires the "image/png"
package import.
Also note that the y
coordinate given will be the bottom line of the text. So if you want to draw a line to the top left corner, you have to use x = 0
and y = 13
(13 is the height of this Face7x13
font). If you wish, you could build this into the addLabel()
function by subtracting 13
from the y
coordinate, so that the passed y
coordinate would be the top coordinate at which the text will be drawn.
There is also an additional self-contained font in the golang.org/x/image/font/inconsolata
package with regular and bold style, to use them, you only need to specify a different Face
in addLabel()
:
import "golang.org/x/image/font/inconsolata"
// To use regular Inconsolata font family:
Face: inconsolata.Regular8x16,
// To use bold Inconsolata font family:
Face: inconsolata.Bold8x16,