-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
anaglyph.go
100 lines (82 loc) · 2.22 KB
/
anaglyph.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 mpo
import (
"errors"
"image"
"image/color"
)
type colorType int
const (
// RedCyan is Red on left eye, cyan on right
RedCyan colorType = iota
// CyanRed is Cyan on left eye, red on right
CyanRed
// RedGreen is Red on left eye, green on right
RedGreen
// GreenRed is Green on left eye, red on right
GreenRed
)
// ErrInvalidImageCount indicates that incorrect number of images were found
// during the anaglyph conversion process.
var ErrInvalidImageCount = errors.New("anaglph conversion only supports 2 image")
// ErrInconsistentBounds indicates that not all images within the MPO file were
// found to be the same size, which is a requirement for the anaglyph conversion.
var ErrInconsistentBounds = errors.New("anaglyph images must be the same size")
// ConvertToAnaglyph converts an MPO to the anaglyph format specified by ct colorType constant
func (m *MPO) ConvertToAnaglyph(ct colorType) (image.Image, error) {
if len(m.Image) != 2 {
return nil, ErrInvalidImageCount
}
left := m.Image[0]
right := m.Image[1]
if !left.Bounds().Eq(right.Bounds()) {
return nil, ErrInconsistentBounds
}
img := image.NewRGBA(left.Bounds())
for x := 0; x <= left.Bounds().Max.X; x++ {
for y := 0; y <= left.Bounds().Max.Y; y++ {
lr, lg, lb, _ := left.At(x, y).RGBA()
rr, rg, rb, _ := right.At(x, y).RGBA()
lgs := (((float32(lr) / 65535) * .229) * 65535) +
(((float32(lg) / 65535) * .587) * 65535) +
(((float32(lb) / 65535) * .144) * 65535)
rgs := (((float32(rr) / 65535) * .229) * 65535) +
(((float32(rg) / 65535) * .587) * 65535) +
(((float32(rb) / 65535) * .144) * 65535)
var c color.RGBA64
switch ct {
case RedCyan:
c = color.RGBA64{
R: uint16(lgs),
G: uint16(rg),
B: uint16(rb),
A: 65535,
}
case CyanRed:
c = color.RGBA64{
R: uint16(rgs),
G: uint16(lg),
B: uint16(lb),
A: 65535,
}
case RedGreen:
c = color.RGBA64{
R: uint16(lgs),
G: uint16(rgs),
B: 65535 / 2,
A: 65535,
}
case GreenRed:
c = color.RGBA64{
R: uint16(rgs),
G: uint16(lgs),
B: 65535 / 2,
A: 65535,
}
default:
return nil, errors.New("unsupported color type")
}
img.Set(x, y, c)
}
}
return img, nil
}