-
Notifications
You must be signed in to change notification settings - Fork 6
/
png.go
100 lines (90 loc) · 2.17 KB
/
png.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
package main
import (
"errors"
"image"
"image/draw"
"image/png"
"math"
"os"
"github.com/fiam/max7456tool/mcm"
"github.com/urfave/cli/v2"
)
func buildPNGFromMCM(ctx *cli.Context, output string, input string) error {
mf, err := os.Open(input)
if err != nil {
return err
}
defer mf.Close()
dec, err := mcm.NewDecoder(mf)
if err != nil {
return err
}
cols := ctx.Int("columns")
margin := ctx.Int("margin")
rows := int(math.Ceil(float64(dec.NChars()) / float64(cols)))
imageWidth := (mcm.CharWidth+margin)*cols + margin
imageHeight := (mcm.CharHeight+margin)*rows + margin
img := image.NewRGBA(image.Rect(0, 0, imageWidth, imageHeight))
// Top and left sides of the grid
for x := 0; x < imageWidth; x++ {
for y := 0; y < margin; y++ {
img.Set(x, y, mcm.BlackColor)
}
}
for x := 0; x < margin; x++ {
for y := 0; y < imageHeight; y++ {
img.Set(x, y, mcm.BlackColor)
}
}
// Draw each character
for ii := 0; ii < cols; ii++ {
for jj := 0; jj < rows; jj++ {
leftX := ii*(mcm.CharWidth+margin) + margin
rightX := leftX + mcm.CharWidth + margin
topY := jj*(mcm.CharHeight+margin) + margin
bottomY := topY + mcm.CharHeight + margin
// Draw right line
for x := rightX - margin; x < rightX; x++ {
for y := topY; y < bottomY; y++ {
img.Set(x, y, mcm.BlackColor)
}
}
// Draw bottom line
for x := leftX; x < rightX; x++ {
for y := bottomY - margin; y < bottomY; y++ {
img.Set(x, y, mcm.BlackColor)
}
}
// Draw character
chn := (jj * cols) + ii
if chn >= dec.NChars() {
continue
}
r := image.Rect(leftX, topY, leftX+mcm.CharWidth, topY+mcm.CharHeight)
ch := dec.CharAt(chn)
cim := ch.Image(nil)
draw.Draw(img, r, cim, image.ZP, draw.Over)
}
}
// Save to png
f, err := openOutputFile(output)
if err != nil {
return err
}
defer f.Close()
if err := png.Encode(f, img); err != nil {
return err
}
if err := f.Close(); err != nil {
return err
}
return nil
}
func pngAction(ctx *cli.Context) error {
if ctx.NArg() != 2 {
return errors.New("png requires 2 arguments, see help png")
}
input := ctx.Args().Get(0)
output := ctx.Args().Get(1)
return buildPNGFromMCM(ctx, output, input)
}