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 |
package main
import (
"fmt"
"image"
"image/draw"
)
func hex(num uint) string {
temp := []byte{'0', '0', '0', '0', '0', '0'}
for counter := 0; num > 0; counter++ {
n := uint8(num & 0xF)
if n < 10 {
temp[5-counter] = '0' + n
} else {
temp[5-counter] = ('A' - 10) + n
}
num >>= 4
}
return string(temp)
}
func gray(r, g, b uint8) uint8 {
return r/5 + uint8(uint(g)*7/10) + b/10
}
func grayscale(img image.Image) {
a := img.(*image.RGBA)
for i := a.PixOffset(0, 0); i < len(a.Pix); i += 4 {
g := gray(a.Pix[i], a.Pix[i+1], a.Pix[i+2])
a.Pix[i] = g
a.Pix[i+1] = g
a.Pix[i+2] = g
}
}
func monochrome(img image.Image) {
a := img.(*image.RGBA)
for i := a.PixOffset(0, 0); i < len(a.Pix); i += 4 {
g := gray(a.Pix[i], a.Pix[i+1], a.Pix[i+2]) / 128 * 255
a.Pix[i] = g
a.Pix[i+1] = g
a.Pix[i+2] = g
}
}
func resize(original image.Image, w, h int) (image.Image, error) {
src, ok := original.(*image.RGBA)
if !ok {
b := original.Bounds()
src = image.NewRGBA(b)
draw.Draw(src, b, original, b.Min, draw.Src)
}
width := src.Bounds().Dx()
height := src.Bounds().Dy()
if width < 1 || height < 1 {
return image.Image(src), fmt.Errorf("image dimensions invalid -- %v, %v", width, height)
}
if h == 0 {
h = int(float32(w) / (float32(width) / float32(height)))
}
if w < 1 || h < 1 {
return image.Image(src), fmt.Errorf("resize values invalid -- %v, %v", w, h)
}
dst := image.NewRGBA(image.Rect(0, 0, w, h))
xRatio := float32(width) / float32(w)
yRatio := float32(height) / float32(h)
if width > w {
b := src.Bounds()
i := src.PixOffset(0, 0)
checklist := make([]bool, len(dst.Pix)>>2)
for y := b.Min.Y; y < b.Max.Y; y++ {
oy := int(float32(y) / yRatio)
for x := b.Min.X; x < b.Max.X; x++ {
ox := int(float32(x) / xRatio)
o := dst.PixOffset(ox, oy)
if !checklist[o>>2] {
checklist[o>>2] = true
dst.Pix[o+0] = src.Pix[i+0]
dst.Pix[o+1] = src.Pix[i+1]
dst.Pix[o+2] = src.Pix[i+2]
dst.Pix[o+3] = src.Pix[i+3]
} else {
dst.Pix[o+0] = uint8((uint64(dst.Pix[o+0]) + uint64(src.Pix[i+0])) >> 1)
dst.Pix[o+1] = uint8((uint64(dst.Pix[o+1]) + uint64(src.Pix[i+1])) >> 1)
dst.Pix[o+2] = uint8((uint64(dst.Pix[o+2]) + uint64(src.Pix[i+2])) >> 1)
dst.Pix[o+3] = uint8((uint64(dst.Pix[o+3]) + uint64(src.Pix[i+3])) >> 1)
}
i += 4
}
}
} else {
b := dst.Bounds()
i := dst.PixOffset(0, 0)
for y := b.Min.Y; y < b.Max.Y; y++ {
oy := int(float32(y) * yRatio)
for x := b.Min.X; x < b.Max.X; x++ {
ox := int(float32(x) * xRatio)
o := src.PixOffset(ox, oy)
dst.Pix[i+0] = src.Pix[o+0]
dst.Pix[i+1] = src.Pix[o+1]
dst.Pix[i+2] = src.Pix[o+2]
dst.Pix[i+3] = src.Pix[o+3]
i += 4
}
}
}
return dst, nil
}
|