-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
137 lines (116 loc) · 2.72 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
package main
import (
"errors"
"fmt"
"image"
"image/color"
"image/draw"
"os"
"path/filepath"
"golang.org/x/exp/shiny/driver"
"golang.org/x/exp/shiny/screen"
"golang.org/x/mobile/event/lifecycle"
"golang.org/x/mobile/event/paint"
"golang.org/x/mobile/event/size"
"github.com/nfnt/resize"
)
const (
maxw = 3840
maxh = 2160
minw = 400
minh = 400
irw = 1280
irh = 720
)
func main() {
// open image file
if len(os.Args) < 2 {
err := errors.New("no filename given")
chk(err)
}
filename := os.Args[1]
mf, err := os.Open(filename)
chk(err)
// decode image and resize to max
m, mt, err := image.Decode(mf)
chk(err)
omw, omh := m.Bounds().Dx(), m.Bounds().Dy()
m = resize.Thumbnail(maxw, maxh, m, resize.Lanczos3)
// create initial resized image
rm := resize.Thumbnail(irw, irh, m, resize.NearestNeighbor)
rmw, rmh := rm.Bounds().Dx(), rm.Bounds().Dy()
driver.Main(func(s screen.Screen) {
// create window sized to resized image
title := fmt.Sprintf("%s (%s/%d*%d)", filepath.Base(filename), mt, omw, omh)
ww := rmw
if ww < minw {
ww = minw
}
wh := rmh
if wh < minh {
wh = minh
}
wnd, err := s.NewWindow(&screen.NewWindowOptions{
Width: ww,
Height: wh,
Title: title,
})
chk(err)
wr := image.Rect(0, 0, ww, wh)
// create initial buffer and draw image to it
buf, err := s.NewBuffer(rm.Bounds().Size())
chk(err)
draw.Draw(buf.RGBA(), buf.Bounds(), rm, image.Point{}, draw.Src)
for {
// wait for next event and handle
switch e := wnd.NextEvent().(type) {
// window close
case lifecycle.Event:
if e.To == lifecycle.StageDead {
return
}
// window resize (or close on macOS)
case size.Event:
// update window rectangle
wr = e.Bounds()
// check to close window on macOS
if wr.Empty() {
return
}
// other paint
case paint.Event:
// if image size has changed since last paint
if !m.Bounds().In(wr) {
// release old buffer
buf.Release()
// create new resized image and buffer
rm = resize.Thumbnail(uint(wr.Dx()), uint(wr.Dy()), m, resize.NearestNeighbor)
buf, err = s.NewBuffer(rm.Bounds().Size())
chk(err)
// draw image to buffer
draw.Draw(buf.RGBA(), buf.Bounds(), rm, image.Point{}, draw.Src)
}
// calculate new starting point
sp := image.Pt(
(wr.Dx()-rm.Bounds().Dx())/2,
(wr.Dy()-rm.Bounds().Dy())/2,
)
// fill window as black
wnd.Fill(wr, color.Black, draw.Src)
// upload buffer to window at starting point and publish
wnd.Upload(sp, buf, buf.Bounds())
wnd.Publish()
}
}
})
}
func init() {
err := loadPlugins()
chk(err)
}
func chk(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "eiv: %s\n", err)
os.Exit(1)
}
}