fusenapi/utils/qrcode/creator.go
laodaming 748e707dfa fix
2023-06-16 11:15:38 +08:00

123 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package qrcode
import (
"bytes"
"encoding/base64"
"github.com/nfnt/resize"
"github.com/skip2/go-qrcode"
"golang.org/x/image/draw"
"image"
"image/color"
_ "image/jpeg"
"image/png"
"os"
)
type CreateQrCodeBs64WithLogoReq struct {
Content string //二维码内容
OutPath *string //二维码保存路径(可选)
LogoPath *string //logo路径可选
Size int64 //二维码尺寸
X *int64 //二维码整体x偏移
Y *int64 //二维码整体Y偏移
ForegroundColor *color.Color //二维码纹路颜色
BackgroundColor *color.Color //二维码背景颜色
DisableBorder bool // 是否不要二维码边框
}
func CreateQrCodeBs64WithLogo(req CreateQrCodeBs64WithLogoReq) (data string, err error) {
code, err := qrcode.New(req.Content, qrcode.High)
if err != nil {
return
}
if req.DisableBorder {
code.DisableBorder = true
}
//二维码纹路颜色
if req.ForegroundColor != nil {
code.ForegroundColor = *req.ForegroundColor
}
//背景颜色
if req.BackgroundColor != nil {
code.BackgroundColor = *req.BackgroundColor
}
//设置文件大小并创建画板
qrcodeImg := code.Image(int(req.Size))
outImg := image.NewRGBA(qrcodeImg.Bounds())
buf := new(bytes.Buffer)
//无logo
if req.LogoPath == nil {
//图像偏移
if req.X != nil && req.Y != nil {
draw.Draw(outImg, outImg.Bounds().Add(image.Pt(int(*req.X), int(*req.Y))), qrcodeImg, outImg.Bounds().Min, draw.Src)
}
err = png.Encode(buf, outImg)
if err != nil {
return "", err
}
if req.OutPath != nil {
// 写入文件
f, err := os.Create(*req.OutPath)
if err != nil {
return "", err
}
defer f.Close()
err = png.Encode(f, outImg)
if err != nil {
return "", err
}
}
return base64.StdEncoding.EncodeToString(buf.Bytes()), nil
}
//读取logo文件
logoFile, err := os.Open(*req.LogoPath)
if err != nil {
return "", err
}
logoImg, _, err := image.Decode(logoFile)
if err != nil {
return "", err
}
logoImg = resize.Resize(uint(req.Size/5), uint(req.Size/5), logoImg, resize.Lanczos3)
// 添加边框
// 图片到边框距离
pic2FramePadding := logoImg.Bounds().Dx() / 10
// 新建一个边框图层
transparentImg := image.NewRGBA(image.Rect(0, 0, logoImg.Bounds().Dx()+pic2FramePadding, logoImg.Bounds().Dy()+pic2FramePadding))
// 图层颜色设为白色
draw.Draw(transparentImg, transparentImg.Bounds(), image.White, image.Point{}, draw.Over)
// 将缩略图放到透明图层上
draw.Draw(transparentImg,
image.Rect(pic2FramePadding/2, pic2FramePadding/2, transparentImg.Bounds().Dx(), transparentImg.Bounds().Dy()),
logoImg,
image.Point{},
draw.Over)
//logo和二维码拼接
draw.Draw(outImg, outImg.Bounds(), qrcodeImg, image.Pt(0, 0), draw.Over)
offset := image.Pt((outImg.Bounds().Max.X-transparentImg.Bounds().Max.X)/2, (outImg.Bounds().Max.Y-transparentImg.Bounds().Max.Y)/2)
draw.Draw(outImg, outImg.Bounds().Add(offset), transparentImg, image.Pt(0, 0), draw.Over)
//图像偏移
if req.X != nil && req.Y != nil {
draw.Draw(outImg, outImg.Bounds().Add(image.Pt(int(*req.X), int(*req.Y))), qrcodeImg, outImg.Bounds().Min, draw.Src)
}
err = png.Encode(buf, outImg)
if err != nil {
return "", err
}
if req.OutPath != nil {
// 写入文件
f, err := os.Create(*req.OutPath)
if err != nil {
return "", err
}
defer f.Close()
err = png.Encode(f, outImg)
if err != nil {
return "", err
}
}
return base64.StdEncoding.EncodeToString(buf.Bytes()), nil
}