-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
514 additions
and
198 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,70 +1,28 @@ | ||
package handler | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"github.com/bitqiu/pix-gen/captcha" | ||
"github.com/bitqiu/pix-gen/fonts" | ||
"github.com/bitqiu/pix-gen/pkg/captcha" | ||
"github.com/gin-gonic/gin" | ||
"image/png" | ||
"net/http" | ||
"strconv" | ||
) | ||
|
||
var cap *captcha.Captcha | ||
|
||
var defaultWidth = 120 | ||
var defaultHeight = 30 | ||
|
||
// HandleCaptcha 处理验证码生成请求的处理程序 | ||
func HandleCaptcha(c *gin.Context) { | ||
cap = captcha.New() | ||
cap.SetDisturbance(captcha.NORMAL) | ||
//cap.SetFrontColor(color.RGBA{255, 0, 0, 255}, color.RGBA{0, 0, 255, 255}, color.RGBA{0, 153, 0, 255}) | ||
fontBytes, err := fonts.FontsFS.ReadFile("MiSans-Normal.ttf") | ||
if err != nil { | ||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid"}) | ||
return | ||
} | ||
err = cap.AddFontFromBytes(fontBytes) | ||
if err != nil { | ||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid font"}) | ||
return | ||
} | ||
|
||
// 解析width和height参数,如果不存在则使用默认值 | ||
widthStr := c.DefaultQuery("width", fmt.Sprintf("%d", defaultWidth)) | ||
heightStr := c.DefaultQuery("height", fmt.Sprintf("%d", defaultHeight)) | ||
|
||
// 转换字符串为int,并增加错误处理 | ||
width, err := strconv.ParseInt(widthStr, 10, 64) | ||
if err != nil { | ||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid width format"}) | ||
return | ||
} | ||
height, err := strconv.ParseInt(heightStr, 10, 64) | ||
if err != nil { | ||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid height format"}) | ||
return | ||
} | ||
|
||
// 检查code参数,如果存在则尝试解码验证码 | ||
// 获取并解析 width 和 height 参数,如果不存在则使用默认值 | ||
widthStr := c.DefaultQuery("width", fmt.Sprintf("%d", 120)) | ||
heightStr := c.DefaultQuery("height", fmt.Sprintf("%d", 30)) | ||
code := c.Query("code") | ||
|
||
// 检查width和height的边界条件 | ||
if width <= 0 || height <= 0 { | ||
c.JSON(http.StatusBadRequest, gin.H{"error": "Width and height must be positive integers"}) | ||
// 调用 captcha 包生成验证码 | ||
captchaImage, err := captcha.GenerateCaptcha(widthStr, heightStr, code) | ||
if err != nil { | ||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) | ||
return | ||
} | ||
cap.SetSize(int(width), int(height)) | ||
|
||
// 生成新的验证码 | ||
img := cap.CreateCustom(code) | ||
// 返回验证码图像 | ||
c.Data(http.StatusOK, "image/png", captchaImage) | ||
|
||
// 直接输出二进制图像数据 | ||
buffer := new(bytes.Buffer) | ||
if err := png.Encode(buffer, img); err != nil { | ||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to encode image"}) | ||
return | ||
} | ||
c.Data(http.StatusOK, "image/png", buffer.Bytes()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,85 +1,26 @@ | ||
package handler | ||
|
||
import ( | ||
"fmt" | ||
qc "github.com/bitqiu/pix-gen/pkg/qrcode" | ||
"github.com/gin-gonic/gin" | ||
"github.com/skip2/go-qrcode" | ||
"image/color" | ||
"net/http" | ||
"strconv" | ||
"strings" | ||
) | ||
|
||
// HandleQrcode 是处理生成二维码请求的处理程序 | ||
func HandleQrcode(c *gin.Context) { | ||
text := c.DefaultQuery("text", "null") | ||
level := c.DefaultQuery("level", "H") | ||
sizeQuery := c.DefaultQuery("size", fmt.Sprintf("%d", 300)) | ||
colorQuery := c.DefaultQuery("color", "000000") | ||
|
||
// 转换字符串为int,并增加错误处理 | ||
size, err := strconv.ParseInt(sizeQuery, 10, 64) | ||
text := c.DefaultQuery("text", "null") // 获取二维码的内容,默认为 "null" | ||
level := c.DefaultQuery("level", "H") // 获取错误校验级别,默认为 "H" | ||
sizeQuery := c.DefaultQuery("size", "300") // 获取二维码大小,默认为 300 | ||
colorQuery := c.DefaultQuery("color", "000000") // 获取前景颜色,默认为黑色 | ||
marginQuery := c.DefaultQuery("margin", "0") // 获取边距大小,默认为 0 | ||
|
||
// 调用 qc 包生成二维码 | ||
qrCode, err := qc.GenerateQRCode(text, level, sizeQuery, colorQuery, marginQuery) | ||
if err != nil { | ||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid size format"}) | ||
return | ||
} | ||
|
||
// 设置错误校验级别 | ||
qrLevel := qrcode.Medium | ||
switch level { | ||
case "L": | ||
qrLevel = qrcode.Low | ||
case "M": | ||
qrLevel = qrcode.Medium | ||
case "Q": | ||
qrLevel = qrcode.High | ||
case "H": | ||
qrLevel = qrcode.Highest | ||
default: | ||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid QR code level"}) | ||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) | ||
return | ||
} | ||
|
||
qrc, err := qrcode.New(text, qrLevel) | ||
if err != nil { | ||
c.JSON(http.StatusBadRequest, "Failed to create QR code") | ||
return | ||
} | ||
qrc.DisableBorder = true | ||
|
||
rgbaColor, err := hexToRGBA(colorQuery) | ||
if err != nil { | ||
c.JSON(http.StatusBadRequest, "Invalid color format") | ||
return | ||
} | ||
qrc.ForegroundColor = rgbaColor | ||
|
||
png, errEncode := qrc.PNG(int(size)) | ||
if errEncode != nil { | ||
c.JSON(http.StatusBadRequest, "Failed to encode QR code image") | ||
return | ||
} | ||
|
||
c.Data(http.StatusOK, "image/png", png) | ||
|
||
} | ||
|
||
// hexToRGBA 将16进制颜色转换为RGBA。 | ||
func hexToRGBA(hex string) (color.RGBA, error) { | ||
hex = strings.TrimPrefix(strings.ToLower(hex), "#") | ||
if len(hex) != 6 { | ||
return color.RGBA{}, fmt.Errorf("invalid hex color format") | ||
} | ||
r, err := strconv.ParseUint(hex[:2], 16, 8) | ||
if err != nil { | ||
return color.RGBA{}, err | ||
} | ||
g, err := strconv.ParseUint(hex[2:4], 16, 8) | ||
if err != nil { | ||
return color.RGBA{}, err | ||
} | ||
b, err := strconv.ParseUint(hex[4:], 16, 8) | ||
if err != nil { | ||
return color.RGBA{}, err | ||
} | ||
return color.RGBA{R: uint8(r), G: uint8(g), B: uint8(b), A: 255}, nil | ||
// 返回二维码图像 | ||
c.Data(http.StatusOK, "image/png", qrCode) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.