all repos — captcha @ 364b4304db2a30e1940ea73035bf1b8c4f4f68bf

Go package captcha implements generation and verification of image and audio CAPTCHAs.

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}