forked from makiuchi-d/gozxing
-
Notifications
You must be signed in to change notification settings - Fork 1
/
go_image_luminance_source.go
109 lines (96 loc) · 2.62 KB
/
go_image_luminance_source.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
package gozxing
import (
"image"
errors "golang.org/x/xerrors"
)
func NewBinaryBitmapFromImage(img image.Image) (*BinaryBitmap, error) {
src := NewLuminanceSourceFromImage(img)
return NewBinaryBitmap(NewHybridBinarizer(src))
}
type GoImageLuminanceSource struct {
*RGBLuminanceSource
}
func NewLuminanceSourceFromImage(img image.Image) LuminanceSource {
rect := img.Bounds()
width := rect.Max.X - rect.Min.X
height := rect.Max.Y - rect.Min.Y
luminance := make([]byte, width*height)
index := 0
// Optimize special cases.
switch img := img.(type) {
case *image.Gray:
for y := rect.Min.Y; y < rect.Max.Y; y++ {
for x := rect.Min.X; x < rect.Max.X; x++ {
y := img.GrayAt(x, y).Y
luminance[index] = y
index++
}
}
case image.RGBA64Image:
for y := rect.Min.Y; y < rect.Max.Y; y++ {
for x := rect.Min.X; x < rect.Max.X; x++ {
r, g, b, a := img.RGBA64At(x, y).RGBA()
lum := (r + 2*g + b) * 255 / (4 * 0xffff)
luminance[index] = byte((lum*a + (0xffff-a)*255) / 0xffff)
index++
}
}
default:
for y := rect.Min.Y; y < rect.Max.Y; y++ {
for x := rect.Min.X; x < rect.Max.X; x++ {
r, g, b, a := img.At(x, y).RGBA()
lum := (r + 2*g + b) * 255 / (4 * 0xffff)
luminance[index] = byte((lum*a + (0xffff-a)*255) / 0xffff)
index++
}
}
}
return &GoImageLuminanceSource{&RGBLuminanceSource{
LuminanceSourceBase{width, height},
luminance,
width,
height,
0,
0,
}}
}
func (this *GoImageLuminanceSource) Crop(left, top, width, height int) (LuminanceSource, error) {
cropped, e := this.RGBLuminanceSource.Crop(left, top, width, height)
if e != nil {
return nil, e
}
return &GoImageLuminanceSource{cropped.(*RGBLuminanceSource)}, nil
}
func (this *GoImageLuminanceSource) Invert() LuminanceSource {
return LuminanceSourceInvert(this)
}
func (this *GoImageLuminanceSource) IsRotateSupported() bool {
return true
}
func (this *GoImageLuminanceSource) RotateCounterClockwise() (LuminanceSource, error) {
width := this.GetWidth()
height := this.GetHeight()
top := this.top
left := this.left
dataWidth := this.dataWidth
oldLuminas := this.RGBLuminanceSource.luminances
newLuminas := make([]byte, width*height)
for j := 0; j < width; j++ {
x := left + width - 1 - j
for i := 0; i < height; i++ {
y := top + i
newLuminas[j*height+i] = oldLuminas[y*dataWidth+x]
}
}
return &GoImageLuminanceSource{&RGBLuminanceSource{
LuminanceSourceBase{height, width},
newLuminas,
height,
width,
0,
0,
}}, nil
}
func (this *GoImageLuminanceSource) RotateCounterClockwise45() (LuminanceSource, error) {
return nil, errors.New("RotateCounterClockwise45 is not implemented")
}