使用 Go 构建图像验证码识别 Web 服务
本文介绍如何使用 Go 编写一个验证码识别 Web 服务,支持通过 HTTP 接口上传图像,并返回识别的验证码文本。适合集成到自动化系统或测试平台中。
技术栈
Go 标准库
net/http
更多内容访问ttocr.com或联系1436423940
image 解码
github.com/nfnt/resize(用于图像缩放)
模拟识别逻辑(可扩展为真实模型)
一、初始化项目
mkdir go-captcha-api && cd go-captcha-api
go mod init go-captcha-api
go get github.com/nfnt/resize
二、项目结构
go-captcha-api/
├── main.go
├── imageutil/
│ └── loader.go
├── recognizer/
│ └── dummy.go
三、图像加载模块 imageutil/loader.go
package imageutil
import (
"image"
"image/jpeg"
"image/png"
"mime/multipart"
"strings"
"github.com/nfnt/resize"
)
func DecodeAndResize(file multipart.File, filename string, w, h int) (image.Image, error) {
var img image.Image
var err error
if strings.HasSuffix(filename, ".png") {
img, err = png.Decode(file)
} else {
img, err = jpeg.Decode(file)
}
if err != nil {
return nil, err
}
return resize.Resize(uint(w), uint(h), img, resize.Lanczos3), nil
}
四、模拟识别模块 recognizer/dummy.go
package recognizer
import (
"math/rand"
"time"
)
var charset = []rune("23456789ABCDEFGHJKLMNPQRSTUVWXYZ")
func Simulate(length int) string {
rand.Seed(time.Now().UnixNano())
result := make([]rune, length)
for i := range result {
result[i] = charset[rand.Intn(len(charset))]
}
return string(result)
}
五、主程序 main.go
package main
import (
"fmt"
"go-captcha-api/imageutil"
"go-captcha-api/recognizer"
"io"
"net/http"
)
func main() {
http.HandleFunc("/recognize", recognizeHandler)
fmt.Println("服务已启动:http://localhost:8080")
http.ListenAndServe(":8080", nil)
}
func recognizeHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "仅支持 POST 方法", http.StatusMethodNotAllowed)
return
}
file, header, err := r.FormFile("image")
if err != nil {
http.Error(w, "图片上传失败", http.StatusBadRequest)
return
}
defer file.Close()
// 为解码器拷贝副本(原文件只能读一次)
data, err := io.ReadAll(file)
if err != nil {
http.Error(w, "读取失败", http.StatusInternalServerError)
return
}
imageReader := io.NopCloser(io.LimitReader(io.NewSectionReader(
io.NewSectionReader(io.NewBufferReader(data), 0, int64(len(data))),
0, int64(len(data)),
), int64(len(data))))
img, err := imageutil.DecodeAndResize(imageReader, header.Filename, 160, 60)
if err != nil {
http.Error(w, "图像解析失败", http.StatusUnsupportedMediaType)
return
}
_ = img // 实际使用时可以用于后续识别模型
result := recognizer.Simulate(4)
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, `{"result": "%s"}`, result)
}
六、测试服务
运行服务:
go run main.go
使用 curl 发送请求:
curl -X POST -F "image=@captcha_samples/ABCD_1.png" http://localhost:8080/recognize
返回示例:
{"result": "X4GJ"}
浙公网安备 33010602011771号