forked from smart--petea/pixl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gray.go
91 lines (73 loc) · 1.84 KB
/
gray.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
package pixl
import (
"image"
"image/color"
)
type grayAlgoName string
type grayAlgoList struct {
Lightness grayAlgoName
Average grayAlgoName
Luminosity grayAlgoName
}
// GrayAlgorithms consists of a list of algorithms that can be used as
// algorithm type in pixl.Gray struct. e.g.
// pixl.Gray{Algorithm: pixl.GrayAlgorithms.Lithtness}
var GrayAlgorithms = &grayAlgoList{
Lightness: "lightness",
Average: "average",
Luminosity: "luminosity",
}
//Gray is a config struct
type Gray struct {
Algorithm grayAlgoName
}
//Convert takes an image as an input and returns grayscale of the image
func (config Gray) Convert(input image.Image) *image.Gray {
output := image.NewGray(input.Bounds())
if config.Algorithm == "lightness" {
traverseImage(input, output, grayLightness{})
} else if config.Algorithm == "average" {
traverseImage(input, output, grayAverage{})
} else { //if conf.Algorithm == "luminosity"
traverseImage(input, output, grayLuminosity{})
}
return output
}
type grayLightness struct{}
func (config grayLightness) transform(input color.Color) color.Color {
r, g, b, _ := input.RGBA()
max := func(a, b uint32) uint32 {
if a > b {
return a
}
return b
}
min := func(a, b uint32) uint32 {
if a < b {
return a
}
return b
}
_max := max(r, max(g, b))
_min := min(r, min(g, b))
result := (_max + _min) / 2
return color.Gray{
Y: uint8(result >> 8),
}
}
type grayAverage struct{}
func (config grayAverage) transform(input color.Color) color.Color {
r, g, b, _ := input.RGBA()
result := (r + g + b) / 3
return color.Gray{
Y: uint8(result >> 8),
}
}
type grayLuminosity struct{}
func (config grayLuminosity) transform(input color.Color) color.Color {
r, g, b, _ := input.RGBA()
result := uint32(0.21*float32(r) + 0.72*float32(g) + 0.07*float32(b))
return color.Gray{
Y: uint8(result >> 8),
}
}