/
hue.go
98 lines (94 loc) · 2.27 KB
/
hue.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
package main
import (
"image"
"math"
cli "github.com/jawher/mow.cli"
"github.com/sgreben/yeetgif/pkg/gifcmd"
"github.com/sgreben/yeetgif/pkg/imaging"
)
func CommandHue(cmd *cli.Cmd) {
cmd.Before = InputAndDuplicate
cmd.Spec = "[OPTIONS] [HUE_OFFSETS_CSV]"
const (
hueModeMul = "mul"
hueModeAdd = "add"
hueModeSub = "sub"
hueModePow = "pow"
hueModeSin = "sin"
)
var (
f = gifcmd.Float{Value: 1.0}
a = gifcmd.Float{Value: 0.1}
x = gifcmd.FloatsCSV{Values: []float64{1.0}}
y = gifcmd.FloatsCSV{Values: []float64{1.0}}
mode = gifcmd.Enum{
Choices: []string{
hueModeMul,
hueModeAdd,
hueModeSub,
hueModePow,
hueModeSin,
},
Value: hueModeAdd,
}
custom = gifcmd.FloatsCSV{}
)
cmd.VarOpt("f frequency", &f, "")
cmd.VarOpt("a amplitude", &a, "")
cmd.VarOpt("x", &x, "")
cmd.VarOpt("y", &y, "")
cmd.VarOpt("m mode", &mode, mode.Help())
cmd.VarArg("HUE_OFFSETS_CSV", &custom, "")
cmd.Action = func() {
var hueF func(float64) float64
switch {
case len(custom.Texts) > 0:
hueF = custom.PiecewiseLinear(0, 1)
default:
hueF = func(t float64) float64 {
return a.Value * math.Sin(math.Pi+2*math.Pi*f.Value*t) / 2
}
}
xF := x.PiecewiseLinear(0, 1)
yF := y.PiecewiseLinear(0, 1)
var modeF func(float64, float64, float64) float64
switch mode.Value {
case hueModeMul:
modeF = func(a, b, c float64) float64 {
return a * b * c
}
case hueModeAdd:
modeF = func(a, b, c float64) float64 {
return a + b + c
}
case hueModeSub:
modeF = func(a, b, c float64) float64 {
return a - b - c
}
case hueModePow:
modeF = func(a, b, c float64) float64 {
return math.Pow(a, b*c)
}
case hueModeSin:
modeF = func(a, b, c float64) float64 {
return a + math.Sin(2*math.Pi*(b+c))
}
}
HuePulse(images, func(x, y, t float64) float64 {
return modeF(hueF(t), xF(x), yF(y))
})
}
}
func HuePulse(images []image.Image, f func(float64, float64, float64) float64) {
n := float64(len(images))
hue := func(i int) {
t := float64(i) / n
b := images[i].Bounds()
w := float64(b.Dx())
h := float64(b.Dy())
images[i] = imaging.AdjustHueRotate(images[i], func(x, y int) float64 {
return f(float64(x-b.Min.X)/w, float64(y-b.Min.Y)/h, t)
})
}
parallel(len(images), hue, "hue")
}