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
41
42func min3(x, y, z uint8) (o uint8) {
43 o = x
44 if y < o {
45 o = y
46 }
47 if z < o {
48 o = z
49 }
50 return
51}
52
53func max3(x, y, z uint8) (o uint8) {
54 o = x
55 if y > o {
56 o = y
57 }
58 if z > o {
59 o = z
60 }
61 return
62}
63
64func setRandomBrightness(c *image.NRGBAColor, max uint8) {
65 minc := min3(c.R, c.G, c.B)
66 maxc := max3(c.R, c.G, c.B)
67 if maxc > max {
68 return
69 }
70 n := rand.Intn(int(max-maxc)) - int(minc)
71 c.R = uint8(int(c.R) + n)
72 c.G = uint8(int(c.G) + n)
73 c.B = uint8(int(c.B) + n)
74}
75
76func fillWithCircles(img *image.NRGBA, color image.NRGBAColor, n, maxradius int) {
77 maxx := img.Bounds().Max.X
78 maxy := img.Bounds().Max.Y
79 for i := 0; i < n; i++ {
80 setRandomBrightness(&color, 255)
81 r := rand.Intn(maxradius-1) + 1
82 drawCircle(img, color, rand.Intn(maxx-r*2)+r, rand.Intn(maxy-r*2)+r, r)
83 }
84}
85
86func drawCirclesLine(img *image.NRGBA, color image.Color) {
87 r := 0
88 maxx := img.Bounds().Max.X
89 maxy := img.Bounds().Max.Y
90 y := rand.Intn(maxy/2+maxy/3) - rand.Intn(maxy/3)
91 for x := 0; x < maxx; x += r {
92 r = rand.Intn(dotSize/2)
93 y += rand.Intn(3) - 1
94 if y <= 0 || y >= maxy {
95 y = rand.Intn(maxy/2) + rand.Intn(maxy/2)
96 }
97 drawCircle(img, color, x, y, r)
98 }
99}
100
101func drawNumber(img *image.NRGBA, number []byte, x, y int, color image.NRGBAColor) {
102 skf := rand.Intn(maxSkew) - maxSkew/2
103 if skf < 0 {
104 x -= skf * numberHeight
105 }
106 for y0 := 0; y0 < numberHeight; y0++ {
107 for x0 := 0; x0 < numberWidth; x0++ {
108 radius := rand.Intn(dotSize/2) + dotSize/2
109 addx := rand.Intn(radius / 4)
110 addy := rand.Intn(radius / 4)
111 if number[y0*numberWidth+x0] == 1 {
112 drawCircle(img, color, x+x0*dotSize+dotSize+addx,
113 y+y0*dotSize+dotSize+addy, radius)
114 }
115 }
116 x += skf
117 }
118}