go get github.com/boombuler/barcode
import (
"github.com/skip2/go-qrcode"
)
//GetQRCodeIO 返回图片字节 content-二维码内容 level-容错级别(越高越好),Low,Medium,High,Highest size-像素单位
func GetQRCodeIO(content string, level qrcode.RecoveryLevel, size int) string {
var png []byte
//固定方法
png, err := qrcode.Encode(content, level, size)
if err != nil {
return ""
}
//文件流需要使用base64编码后才可使用
res := base64.StdEncoding.EncodeToString(png)
fmt.Println(res)
return res
}
会生成下图字节数据
//GetQRCodeFile content-二维码内容 level-容错级别,Low,Medium,High,Highest size-像素单位 outPath-输出路径
func GetQRCodeFile(content, outPath string, level qrcode.RecoveryLevel, size int) interface{} {
//固定方法
err := qrcode.WriteFile(content, level, size, outPath)
if err != nil {
return err.Error()
}
return nil
}
会生成下图文件样式
//GetQRCodeCustom content-二维码内容 level-容错级别,Low,Medium,High,Highest size-像素单位 outPath-输出路径 bColor-前景颜色 gColor-背景颜色
func GetQRCodeCustom(content, outPath string, level qrcode.RecoveryLevel, size int, bColor, gColor color.Color) interface{} {
//固定方法
err := qrcode.WriteColorFile(content, level, size, bColor, gColor, outPath)
if err != nil {
return err.Error()
}
return nil
}
会生成下图文件样式
//CreateQrCodeWithLogo 带logo的二维码图片生成 content-二维码内容 level-容错级别,Low,Medium,High,Highest size-像素单位 outPath-输出路径 logoPath-logo文件路径
func CreateQrCodeWithLogo(content, logoPath, outPath string, level qrcode.RecoveryLevel, size int) interface{} {
code, err := qrcode.New(content, level)
if err != nil {
return err.Error()
}
//设置文件大小并创建画板
qrcodeImg := code.Image(size)
outImg := image.NewRGBA(qrcodeImg.Bounds())
//读取logo文件
logoFile, err := os.Open(logoPath)
if err != nil {
panic(err)
}
logoImg, _, err := image.Decode(logoFile)
logoImg = resize.Resize(uint(size/6), uint(size/6), logoImg, resize.Lanczos3)
//logo和二维码拼接
draw.Draw(outImg, outImg.Bounds(), qrcodeImg, image.Pt(0, 0), draw.Over)
offset := image.Pt((outImg.Bounds().Max.X-logoImg.Bounds().Max.X)/2, (outImg.Bounds().Max.Y-logoImg.Bounds().Max.Y)/2)
draw.Draw(outImg, outImg.Bounds().Add(offset), logoImg, image.Pt(0, 0), draw.Over)
f, err := os.Create(outPath)
if err != nil {
return err.Error()
}
png.Encode(f, outImg)
return nil
}
会生成下图样式文件
//CreateQrCodeCustomWithLogo 带logo的二维码图片生成 content-二维码内容 level-容错级别,Low,Medium,High,Highest size-像素单位 outPath-输出路径 logoPath-logo文件路径
func CreateQrCodeCustomWithLogo(content, logoPath, outPath string, level qrcode.RecoveryLevel, size int) interface{} {
code, err := qrcode.New(content, level)
if err != nil {
return err.Error()
}
//设置文件长宽并创建画板
qrcodeImg := code.Image(size)
outImg := image.NewRGBA(qrcodeImg.Bounds())
//读取logo文件
logoFile, err := os.Open(logoPath)
if err != nil {
panic(err)
}
logoImg, _, err := image.Decode(logoFile)
logoImg = resize.Resize(uint(size/6), uint(size/6), logoImg, resize.Lanczos3)
//添加方形画板
circleImg := code.Image(size/6 + 5)
outCircleImg := image.NewRGBA(circleImg.Bounds())
//将画板与logo拼接到一起并切为圆形
//Circle是主要方法,裁剪圆形方法
draw.DrawMask(outCircleImg, outCircleImg.Bounds(), logoImg, image.ZP, &Circle{image.Pt(size/12, size/12), size / 12}, image.ZP, draw.Over)
//logo和二维码拼接
draw.Draw(outImg, outImg.Bounds(), qrcodeImg, image.Pt(0, 0), draw.Over)
offset := image.Pt((outImg.Bounds().Max.X-outCircleImg.Bounds().Max.X)/2, (outImg.Bounds().Max.Y-logoImg.Bounds().Max.Y)/2)
draw.Draw(outImg, outImg.Bounds().Add(offset), outCircleImg, image.Pt(0, 0), draw.Over)
//再次添加画板
backImg := code.Image(size - size/10)
outBackImg := image.NewRGBA(backImg.Bounds())
//将生成好的二维码与当前画板拼接到一起,然后整个裁剪,但是用这个方法生成的图片大小会变小,
//因此需要算好最后需要的大小,然后输入size,也就是需要的size是 11*size / 10 的大小
//同上Rectangle是主要方法
draw.DrawMask(outBackImg, outBackImg.Bounds(), outImg, image.ZP, &Rectangle{image.Pt((size+(size/10))/2, (size+(size/10))/2), size/2 - size/20, size/2 - size/20}, image.ZP, draw.Over)
f, err := os.Create(outPath)
if err != nil {
return err.Error()
}
png.Encode(f, outBackImg)
return nil
}
会生成下图文件
同样的,当我们需要logo是圆角的时候,我们可以设计一个裁剪圆角的方法,这个可能比较麻烦,我就懒得想了
qrCode.go
package file
import (
"encoding/base64"
"fmt"
"github.com/nfnt/resize"
"github.com/skip2/go-qrcode"
"golang.org/x/image/draw"
"image"
"image/color"
"image/png"
"os"
)
//GetQRCodeIO 返回图片字节 content-二维码内容 level-容错级别(越高越好),Low,Medium,High,Highest size-像素单位
func GetQRCodeIO(content string, level qrcode.RecoveryLevel, size int) string {
var png []byte
png, err := qrcode.Encode(content, level, size)
if err != nil {
return ""
}
res := base64.StdEncoding.EncodeToString(png)
fmt.Println(res)
return res
}
//GetQRCodeFile content-二维码内容 level-容错级别,Low,Medium,High,Highest size-像素单位 outPath-输出路径
func GetQRCodeFile(content, outPath string, level qrcode.RecoveryLevel, size int) interface{} {
err := qrcode.WriteFile(content, level, size, outPath)
if err != nil {
return err.Error()
}
return nil
}
//GetQRCodeCustom content-二维码内容 level-容错级别,Low,Medium,High,Highest size-像素单位 outPath-输出路径 bColor-前景颜色 gColor-背景颜色
func GetQRCodeCustom(content, outPath string, level qrcode.RecoveryLevel, size int, bColor, gColor color.Color) interface{} {
err := qrcode.WriteColorFile(content, level, size, bColor, gColor, outPath)
if err != nil {
return err.Error()
}
return nil
}
//CreateQrCodeWithLogo 带logo的二维码图片生成 content-二维码内容 level-容错级别,Low,Medium,High,Highest size-像素单位 outPath-输出路径 logoPath-logo文件路径
func CreateQrCodeWithLogo(content, logoPath, outPath string, level qrcode.RecoveryLevel, size int) interface{} {
code, err := qrcode.New(content, level)
if err != nil {
return err.Error()
}
//设置文件大小并创建画板
qrcodeImg := code.Image(size)
outImg := image.NewRGBA(qrcodeImg.Bounds())
//读取logo文件
logoFile, err := os.Open(logoPath)
if err != nil {
panic(err)
}
logoImg, _, err := image.Decode(logoFile)
logoImg = resize.Resize(uint(size/6), uint(size/6), logoImg, resize.Lanczos3)
//logo和二维码拼接
draw.Draw(outImg, outImg.Bounds(), qrcodeImg, image.Pt(0, 0), draw.Over)
offset := image.Pt((outImg.Bounds().Max.X-logoImg.Bounds().Max.X)/2, (outImg.Bounds().Max.Y-logoImg.Bounds().Max.Y)/2)
draw.Draw(outImg, outImg.Bounds().Add(offset), logoImg, image.Pt(0, 0), draw.Over)
f, err := os.Create(outPath)
if err != nil {
return err.Error()
}
png.Encode(f, outImg)
return nil
}
//CreateQrCodeCustomWithLogo 带logo的二维码图片生成 content-二维码内容 level-容错级别,Low,Medium,High,Highest size-像素单位 outPath-输出路径 logoPath-logo文件路径
func CreateQrCodeCustomWithLogo(content, logoPath, outPath string, level qrcode.RecoveryLevel, size int) interface{} {
code, err := qrcode.New(content, level)
if err != nil {
return err.Error()
}
qrcodeImg := code.Image(size)
outImg := image.NewRGBA(qrcodeImg.Bounds())
logoFile, err := os.Open(logoPath)
if err != nil {
panic(err)
}
logoImg, _, err := image.Decode(logoFile)
logoImg = resize.Resize(uint(size/6), uint(size/6), logoImg, resize.Lanczos3)
//添加方形画板
circleImg := code.Image(size/6 + 5)
outCircleImg := image.NewRGBA(circleImg.Bounds())
//logo切为圆形
draw.DrawMask(outCircleImg, outCircleImg.Bounds(), logoImg, image.ZP, &Circle{image.Pt(size/12, size/12), size / 12}, image.ZP, draw.Over)
//logo和二维码拼接
draw.Draw(outImg, outImg.Bounds(), qrcodeImg, image.Pt(0, 0), draw.Over)
offset := image.Pt((outImg.Bounds().Max.X-outCircleImg.Bounds().Max.X)/2, (outImg.Bounds().Max.Y-logoImg.Bounds().Max.Y)/2)
draw.Draw(outImg, outImg.Bounds().Add(offset), outCircleImg, image.Pt(0, 0), draw.Over)
//再次添加画板
backImg := code.Image(size - size/10)
outBackImg := image.NewRGBA(backImg.Bounds())
draw.DrawMask(outBackImg, outBackImg.Bounds(), outImg, image.ZP, &Rectangle{image.Pt((size+(size/10))/2, (size+(size/10))/2), size/2 - size/20, size/2 - size/20}, image.ZP, draw.Over)
f, err := os.Create(outPath)
if err != nil {
return err.Error()
}
png.Encode(f, outBackImg)
return nil
}
circle.go
package file
import (
"image"
"image/color"
)
type Circle struct {
P image.Point
R int
}
func (c *Circle) ColorModel() color.Model {
return color.AlphaModel
}
func (c *Circle) Bounds() image.Rectangle {
return image.Rect(c.P.X-c.R, c.P.Y-c.R, c.P.X+c.R, c.P.Y+c.R)
}
func (c *Circle) At(x, y int) color.Color {
xx, yy, rr := float64(x-c.P.X), float64(y-c.P.Y), float64(c.R)
if xx*xx+yy*yy < rr*rr {
return color.Alpha{A: 255}
}
return color.Alpha{}
}
rectangle.go
package file
import (
"image"
"image/color"
)
type Rectangle struct {
P image.Point
W int
H int
}
func (r *Rectangle) ColorModel() color.Model {
return color.AlphaModel
}
func (r *Rectangle) Bounds() image.Rectangle {
return image.Rect(r.P.X-r.W, r.P.Y-r.H, r.P.X+r.W, r.P.Y+r.H)
}
func (r *Rectangle) At(x, y int) color.Color {
xx, yy, ww, hh := float64(x-r.P.X), float64(y-r.P.Y), float64(r.W), float64(r.H)
if xx*xx+yy*yy < ww*ww+hh*hh {
return color.Alpha{A: 255}
}
return color.Alpha{}
}
main.go
func main() {
//这里我用的gin框架,框架不重要,重要的是使用
r := gin.Default()
r.POST("/testQR", func(context *gin.Context) {
file.GetQRCodeIO("https://www.baidu.com", qrcode.Medium, 256)
file.GetQRCodeFile("https://www.baidu.com", "config/qrCode1.png", qrcode.Medium, 256)
file.GetQRCodeCustom("https://www.baidu.com", "config/qrCode2.png", qrcode.Medium, 256,
color.RGBA{R: 50, G: 50, B: 50, A: 50}, color.RGBA{R: 255, G: 255, B: 255, A: 255})
file.CreateQrCodeWithLogo("https://www.baidu.com", "E:\\图片\\头像\\2a085da2a850392d0d2b6d840d4dc4e5.jpeg",
"config/qrCode3.png", qrcode.Medium, 256)
file.CreateQrCodeCustomWithLogo("https://www.baidu.com", "E:\\图片\\头像\\2a085da2a850392d0d2b6d840d4dc4e5.jpeg",
"config/qrCode4.png", qrcode.Medium, 256)
})
r.Run(":10006")
}