draw.go 2.0 KB

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