-
Notifications
You must be signed in to change notification settings - Fork 0
/
chloe.go
101 lines (82 loc) · 2.01 KB
/
chloe.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package main
import (
"bytes"
"github.com/golang/freetype"
"github.com/golang/freetype/truetype"
"image"
"image/color"
"image/draw"
"image/jpeg"
"image/png"
"log"
)
const (
srcImage = "assets/chloe.png"
fontFile = "assets/LiberationSans-Regular.ttf"
)
var srcPng image.Image
var srcFont *truetype.Font
// Load source image and font on initialisation
func init() {
srcPng, _ = loadImage()
srcFont, _ = loadFont()
}
// Load source image from assets
func loadImage() (image.Image, error) {
imgFile, _ := Asset(srcImage)
reader := bytes.NewReader(imgFile)
src, err := png.Decode(reader)
return src, err
}
// Load font from assets
func loadFont() (*truetype.Font, error) {
fontBytes, err := Asset(fontFile)
if err != nil {
log.Fatal(err)
}
f, err := freetype.ParseFont(fontBytes)
if err != nil {
log.Fatal(err)
}
return f, err
}
// Stamp puts a given name onto the source image and writes a JPEG into the provided buffer
func Stamp(buffer *bytes.Buffer, name string) {
// Get source image and font
src := srcPng
f := srcFont
// Get source image bounds
bounds := src.Bounds()
// Create a new image based on the source dimensions
img := image.NewRGBA(image.Rect(0, 0, bounds.Dx(), bounds.Dy()))
// Draw the source image onto the target image
draw.Draw(img, img.Bounds(), src, image.ZP, draw.Src)
// Font settings
fg := image.NewUniform(color.RGBA{R: 83, G: 49, B: 95, A: 255})
var fontSize float64 = 20
// Font context
c := freetype.NewContext()
c.SetDPI(72)
c.SetFont(f)
c.SetFontSize(fontSize)
c.SetClip(img.Bounds())
c.SetDst(img)
c.SetSrc(fg)
// Write outside the visible area to get rendered text width
pt := freetype.Pt(2000, 2000)
width, err := c.DrawString(name, pt)
if err != nil {
log.Fatal(err)
}
// Put name right-aligned to 346,410
pt2 := freetype.Pt(346+(2000-width.X.Round()), 410)
_, err = c.DrawString(name, pt2)
if err != nil {
log.Fatal()
}
// Encode as JPEG and write to buffer
err = jpeg.Encode(buffer, img, &jpeg.Options{80})
if err != nil {
log.Fatal(err)
}
}