-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathimages.go
115 lines (89 loc) · 2.54 KB
/
images.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
package main
import (
"fmt"
"image"
"image/color"
"io"
"net/http"
"github.com/fogleman/gg"
"github.com/golang/freetype"
"github.com/golang/freetype/truetype"
"golang.org/x/image/draw"
"golang.org/x/image/font"
"golang.org/x/image/font/gofont/goregular"
)
func createCoverImage(gopherURL, title string) (image.Image, error) {
gopher, err := downloadAndResizeImage(gopherURL)
if err != nil {
return nil, fmt.Errorf("error getting gopher image: %w", err)
}
text, err := createText(title)
if err != nil {
return nil, fmt.Errorf("error creating text image: %w", err)
}
combined, err := combine(gopher, text)
if err != nil {
return nil, fmt.Errorf("error combining images: %w", err)
}
return combined, nil
}
func downloadAndResizeImage(url string) (image.Image, error) {
resp, err := http.Get(url)
if err != nil {
return nil, fmt.Errorf("error making request to get image: %w", err)
}
defer resp.Body.Close()
img, err := resizeImage(resp.Body)
if err != nil {
return nil, fmt.Errorf("error resizing image: %w", err)
}
return img, nil
}
func resizeImage(r io.Reader) (*image.RGBA, error) {
img, _, err := image.Decode(r)
if err != nil {
return nil, fmt.Errorf("error decoding image: %w", err)
}
ratio := 420.0 / float64(img.Bounds().Max.Y)
x := float64(img.Bounds().Max.X) * ratio
scaledImg := image.NewRGBA(image.Rect(0, 0, int(x), 420))
draw.BiLinear.Scale(scaledImg, scaledImg.Rect, img, img.Bounds(), draw.Over, nil)
return scaledImg, nil
}
func createText(text string) (image.Image, error) {
imgWidth := 1000 - 392
imgHeight := 420
dc := gg.NewContext(imgWidth, imgHeight)
ff, err := freetype.ParseFont(goregular.TTF)
if err != nil {
return nil, fmt.Errorf("error creating font: %w", err)
}
dc.SetFontFace(truetype.NewFace(ff, &truetype.Options{
Size: 72,
Hinting: font.HintingFull,
}))
textMargin := 60.0
maxWidth := float64(imgWidth) - textMargin
lineWidth := 1.5
w, _ := dc.MeasureMultilineString(text, lineWidth)
numLines := float64(int(w/maxWidth + 0.5))
if numLines > 3 {
dc.SetFontFace(truetype.NewFace(ff, &truetype.Options{
Size: 50,
Hinting: font.HintingFull,
}))
}
x := float64(imgWidth / 2)
y := float64(imgHeight / 2)
dc.SetColor(color.Black)
dc.DrawStringWrapped(text, x, y, 0.5, 0.5, maxWidth, lineWidth, gg.AlignCenter)
return dc.Image(), nil
}
func combine(gopher, text image.Image) (image.Image, error) {
imgWidth := 1000
imgHeight := 420
dc := gg.NewContext(imgWidth, imgHeight)
dc.DrawImage(gopher, 0, 0)
dc.DrawImage(text, 392, 0)
return dc.Image(), nil
}