golang 生成图片验证码

zhucheer · · 4738 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

在web应用中经常会使用到图片验证码,今天来分享一个图片验证码的生成方案 核心绘图方案利用 `"github.com/fogleman/gg"` 这个包来处理 1.随机获取验证码文字 ``` golang 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.绘制图片将文字写入图片 ``` golang 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](https://img.kancloud.cn/58/6f/586ff08793e2e75544af6ec48c91fe5c_405x235.png) 最后给大家安利一个 web 框架,通过框架快速生成图片验证码完整方案; 快速开始:https://www.kancloud.cn/chase688/orange_framework/content/快速开始.md 图片验证码:https://www.kancloud.cn/chase688/orange_framework/content/tools/图片验证码.md ### 附件 字体 go 文件 https://gitee.com/zhucheer/orange/blob/master/captcha/comic.go

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4738 次点击  
加入收藏 微博
2 回复  |  直到 2021-05-21 22:16:39
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传