forked from lukevers/imgmk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
148 lines (129 loc) · 3.48 KB
/
main.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package main
import (
"bufio"
"flag"
"fmt"
"github.com/lukevers/freetype-go/freetype"
"image"
"image/color"
"image/draw"
"image/png"
"io/ioutil"
"os"
"strconv"
"strings"
)
func main() {
// Parse flags
flag.Parse()
// Check to see if we're passing text in via a unix pipe
fi, err := os.Stdin.Stat()
if err != nil {
fmt.Printf("Error running stat on stdin: %s", err)
os.Exit(1)
}
// Load the font file
file, err := ioutil.ReadFile(*path)
if err != nil {
fmt.Printf("Error loading font from file: %s", err)
os.Exit(1)
}
// Now parse the ttf font
font, err := freetype.ParseFont(file)
if err != nil {
fmt.Printf("Error parsing font: %s", err)
os.Exit(1)
}
// Get the physical image ready with colors/size
var rgbSplit = strings.Split(*rgb, ",")
rgbSplitR, err := strconv.ParseUint(rgbSplit[0], 10, 8)
if err != nil {
fmt.Printf("Error parsing rgb:r: %s", err)
os.Exit(1)
}
rgbSplitG, err := strconv.ParseUint(rgbSplit[1], 10, 8)
if err != nil {
fmt.Printf("Error parsing rgb:g: %s", err)
os.Exit(1)
}
rgbSplitB, err := strconv.ParseUint(rgbSplit[2], 10, 8)
if err != nil {
fmt.Printf("Error parsing rgb:b: %s", err)
os.Exit(1)
}
var fgColor = color.RGBA{R: uint8(rgbSplitR), G: uint8(rgbSplitG), B: uint8(rgbSplitB), A: 255}
fg, bg := image.NewUniform(fgColor), image.White
rgba := image.NewRGBA(image.Rect(0, 0, *width, *height))
// If we passed the transparent flag then we want the
// background to be transparent.
if *transparent {
bg = image.Transparent
}
// Draw the empty image
draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src)
// Create new freetype context to get ready for
// adding text.
c := freetype.NewContext()
c.SetDPI(*dpi)
c.SetFont(font)
c.SetFontSize(*size)
c.SetClip(rgba.Bounds())
c.SetDst(rgba)
c.SetSrc(fg)
c.SetHinting(freetype.NoHinting)
// If we're piping in text then we might have multiple lines,
// and we'll have to draw each line separately.
if fi.Mode()&os.ModeNamedPipe != 0 {
reader := bufio.NewReader(os.Stdin)
var count float64 = 1
for {
line, err := reader.ReadString('\n')
if err != nil {
// When we get here it means we're out of lines,
// so we just break out of here instead of reporting
// any errors.
break
}
drawText(c, line, *size, count)
count++
}
} else {
// If we're down here we're just doing what I assume to be one line,
// which was passed in either not at all (so using default), or by
// the *text flag.
drawText(c, *text, *size, 1)
}
// Create image
image, err := os.Create(*name)
if err != nil {
fmt.Printf("Error creating file: %s", err)
os.Exit(1)
}
// Defer closing of image until we're done, but make sure we actually
// close it.
defer image.Close()
// Write the image and encode it to png.
b := bufio.NewWriter(image)
err = png.Encode(b, rgba)
if err != nil {
fmt.Printf("Error encoding image: %s", err)
os.Exit(1)
}
// This actually writes all the data to the image.
err = b.Flush()
if err != nil {
fmt.Printf("Error flushing bufio writer: %s", err)
os.Exit(1)
}
}
func drawText(c *freetype.Context, text string, size, line float64) {
// We need an offset because we need to know where exactly on the
// image to place the text. The `line` is how much of an offset
// that we need to provide (which line the text is going on).
offsetY := 10 + int(c.PointToFix32(size*line)>>8)
_, err := c.DrawString(text, freetype.Pt(10, offsetY))
if err != nil {
fmt.Println("Could not draw text: %s", err)
os.Exit(1)
}
}