-
-
Notifications
You must be signed in to change notification settings - Fork 110
/
seed.go
69 lines (61 loc) · 1.49 KB
/
seed.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
package triangle
import (
"image"
"image/color"
"math"
)
// seed basic parameters
type seed struct {
a int
m int
randomNum int
div float64
}
// addNoise applies a noise factor, like Adobe's grain filter in order to create a despeckle like image.
func addNoise(amount int, src *image.RGBA) {
size := src.Bounds().Size()
s := &seed{
a: 16807,
m: 0x7fffffff,
randomNum: 1.0,
div: 1.0 / 0x7fffffff,
}
for x := 0; x < size.X; x++ {
for y := 0; y < size.Y; y++ {
noise := (s.random() - 0.01) * float64(amount)
r, g, b, a := src.At(x, y).RGBA()
rf, gf, bf := float64(r>>8), float64(g>>8), float64(b>>8)
// Check if color does not overflow the maximum limit after noise has been applied.
if math.Abs(rf+noise) < 255 && math.Abs(gf+noise) < 255 && math.Abs(bf+noise) < 255 {
rf += noise
gf += noise
bf += noise
}
r2 := Max(0, Min(255, uint8(rf)))
g2 := Max(0, Min(255, uint8(gf)))
b2 := Max(0, Min(255, uint8(bf)))
src.Set(x, y, color.RGBA{R: r2, G: g2, B: b2, A: uint8(a)})
}
}
}
// nextLongRand retrieve the next long random number.
func (s *seed) nextLongRand(seed int) int {
lo := s.a * (seed & 0xffff)
hi := s.a * (seed >> 16)
lo += (hi & 0x7fff) << 16
if lo > s.m {
lo &= s.m
lo++
}
lo += hi >> 15
if lo > s.m {
lo &= s.m
lo++
}
return lo
}
// random generates a random seed.
func (s *seed) random() float64 {
s.randomNum = s.nextLongRand(s.randomNum)
return float64(s.randomNum) * s.div
}