draw.go (view raw)
1package captcha
2
3import (
4 "image"
5 "rand"
6)
7
8func drawHorizLine(img *image.NRGBA, color image.Color, fromX, toX, y int) {
9 for x := fromX; x <= toX; x++ {
10 img.Set(x, y, color)
11 }
12}
13
14func drawCircle(img *image.NRGBA, color image.Color, x0, y0, radius int) {
15 f := 1 - radius
16 ddFx := 1
17 ddFy := -2 * radius
18 x := 0
19 y := radius
20
21 img.Set(x0, y0+radius, color)
22 img.Set(x0, y0-radius, color)
23 drawHorizLine(img, color, x0-radius, x0+radius, y0)
24
25 for x < y {
26 if f >= 0 {
27 y--
28 ddFy += 2
29 f += ddFy
30 }
31 x++
32 ddFx += 2
33 f += ddFx
34 drawHorizLine(img, color, x0-x, x0+x, y0+y)
35 drawHorizLine(img, color, x0-x, x0+x, y0-y)
36 drawHorizLine(img, color, x0-y, x0+y, y0+x)
37 drawHorizLine(img, color, x0-y, x0+y, y0-x)
38 }
39}
40
41func min3(x, y, z uint8) (o uint8) {
42 o = x
43 if y < o {
44 o = y
45 }
46 if z < o {
47 o = z
48 }
49 return
50}
51
52func max3(x, y, z uint8) (o uint8) {
53 o = x
54 if y > o {
55 o = y
56 }
57 if z > o {
58 o = z
59 }
60 return
61}
62
63func setRandomBrightness(c *image.NRGBAColor, max uint8) {
64 minc := min3(c.R, c.G, c.B)
65 maxc := max3(c.R, c.G, c.B)
66 if maxc > max {
67 return
68 }
69 n := rand.Intn(int(max-maxc)) - int(minc)
70 c.R = uint8(int(c.R) + n)
71 c.G = uint8(int(c.G) + n)
72 c.B = uint8(int(c.B) + n)
73}
74
75func fillWithCircles(img *image.NRGBA, color image.NRGBAColor, n, maxradius int) {
76 maxx := img.Bounds().Max.X
77 maxy := img.Bounds().Max.Y
78 for i := 0; i < n; i++ {
79 setRandomBrightness(&color, 255)
80 r := rand.Intn(maxradius-1) + 1
81 drawCircle(img, color, rand.Intn(maxx-r*2)+r, rand.Intn(maxy-r*2)+r, r)
82 }
83}
84
85func drawNumber(img *image.NRGBA, number []byte, x, y int, color image.NRGBAColor) {
86 skf := rand.Intn(maxSkew) - maxSkew/2
87 if skf < 0 {
88 x -= skf * numberHeight
89 }
90 for y0 := 0; y0 < numberHeight; y0++ {
91 for x0 := 0; x0 < numberWidth; x0++ {
92 radius := rand.Intn(dotSize/2) + dotSize/2
93 addx := rand.Intn(radius / 2)
94 addy := rand.Intn(radius / 2)
95 if number[y0*numberWidth+x0] == 1 {
96 drawCircle(img, color, x+x0*dotSize+dotSize+addx,
97 y+y0*dotSize+dotSize+addy, radius)
98 }
99 }
100 x += skf
101 }
102}