all repos — captcha @ caf79f3bd2e22476ecba6f08fb28db4afaf44c17

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
 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}