golang 生成图片验证码

核心绘图方案利用 "github.com/fogleman/gg" 这个包来处理

1.随机获取验证码文字

func GetRandStr(n int) (randStr string) {
    chars := "ABCDEFGHIJKMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789"
    charsLen := len(chars)
    if n > 10 {
        n = 10
    }

    rand.Seed(time.Now().UnixNano())
    for i := 0; i < n; i++ {
        randIndex := rand.Intn(charsLen)
        randStr += chars[randIndex : randIndex+1]
    }
    return randStr
}

2.绘制图片将文字写入图片

func ImgText(width, height int, text string) (b []byte) {
    textLen := len(text)
    dc := gg.NewContext(width, height)
    bgR, bgG, bgB, bgA := getRandColorRange(240, 255)
    dc.SetRGBA255(bgR, bgG, bgB, bgA)
    dc.Clear()

    // 干扰线
    for i := 0; i < 10; i++ {
        x1, y1 := getRandPos(width, height)
        x2, y2 := getRandPos(width, height)
        r, g, b, a := getRandColor(255)
        w := float64(rand.Intn(3) + 1)
        dc.SetRGBA255(r, g, b, a)
        dc.SetLineWidth(w)
        dc.DrawLine(x1, y1, x2, y2)
        dc.Stroke()
    }

    fontSize := float64(height/2) + 5
    face := loadFontFace(fontSize)
    dc.SetFontFace(face)

    for i := 0; i < len(text); i++ {
        r, g, b, _ := getRandColor(100)
        dc.SetRGBA255(r, g, b, 255)
        fontPosX := float64(width/textLen*i) + fontSize*0.6

        writeText(dc, text[i:i+1], float64(fontPosX), float64(height/2))
    }

    buffer := bytes.NewBuffer(nil)
    dc.EncodePNG(buffer)
    b = buffer.Bytes()
    return
}

// 渲染文字
func writeText(dc *gg.Context, text string, x, y float64) {
    xfload := 5 - rand.Float64()*10 + x
    yfload := 5 - rand.Float64()*10 + y

    radians := 40 - rand.Float64()*80
    dc.RotateAbout(gg.Radians(radians), x, y)
    dc.DrawStringAnchored(text, xfload, yfload, 0.2, 0.5)
    dc.RotateAbout(-1*gg.Radians(radians), x, y)
    dc.Stroke()
}

// 随机坐标
func getRandPos(width, height int) (x float64, y float64) {
    x = rand.Float64() * float64(width)
    y = rand.Float64() * float64(height)
    return x, y
}

// 随机颜色
func getRandColor(maxColor int) (r, g, b, a int) {
    r = int(uint8(rand.Intn(maxColor)))
    g = int(uint8(rand.Intn(maxColor)))
    b = int(uint8(rand.Intn(maxColor)))
    a = int(uint8(rand.Intn(255)))
    return r, g, b, a
}

// 随机颜色范围
func getRandColorRange(miniColor, maxColor int) (r, g, b, a int) {
    if miniColor > maxColor {
        miniColor = 0
        maxColor = 255
    }
    r = int(uint8(rand.Intn(maxColor-miniColor) + miniColor))
    g = int(uint8(rand.Intn(maxColor-miniColor) + miniColor))
    b = int(uint8(rand.Intn(maxColor-miniColor) + miniColor))
    a = int(uint8(rand.Intn(maxColor-miniColor) + miniColor))
    return r, g, b, a
}

// 加载字体
func loadFontFace(points float64) font.Face {
     // 这里是将字体TTF文件转换成了 byte 数据保存成了一个 go 文件 文件较大可以到附录下
    // 通过truetype.Parse可以将 byte 类型的数据转换成TTF字体类型
    f, err := truetype.Parse(COMICSAN)if err != nil {
        panic(err)
    }
    face := truetype.NewFace(f, &truetype.Options{
        Size: points,
    })
    return face
}

3.图片生成好了将验证码文字信息暂存到session或redis中等等,然后通过将图片输出到页面,可以是base64也可以是配置content-type输出图片,可以按自己的业务来;
下面是验证码图片效果;

avatar

给大家接受一个 golang web 框架,能快速生成图片验证码完整方案;享受实用主义带来的快乐吧!
快速开始:https://www.kancloud.cn/chase688/orange_framework/content/快速开始.md
图片验证码:https://www.kancloud.cn/chase688/orange_framework/content/tools/图片验证码.md

附件

字体 go 文件 gitee.com/zhucheer/orange/blob/mas...

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!