分享
  1. 首页
  2. 文章

golang 生成个性二维码

hi李昊天 · · 1430 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

前言

好久没发文章了,最近登录看到有朋友评论了golang生成二维码的文章,想了解下生成个性二维码的解决方案!

实现思路 ,网上搜相关资料几乎没有, 没有那就就自己想吧,就去看了下草料二维码;

然后突然就有感觉了 不就是把像素的颜色替换嘛 这还不简单

1 打开二维码图片
2 打开要填充的图片
3 将要填充的图片剪裁成和二维码一样大小
4 分析二维码的每个像素 替换成图片的像素就行了

以下是生成的例子:

例子

image

image

image

image

代码

package main
import (
 "fmt"
 "github.com/nfnt/resize"
 "image"
 "image/color"
 "image/draw"
 "log"
 "os"
 "time"
 _ "image/jpeg"
 _ "image/gif"
 "image/png"
)
func main() {
 // 打开二维码图片
 qrFile, err := os.Open("img/qr.png")
 if err != nil {
 log.Fatalf("打开二维码失败 %s", err.Error())
 return
 }
 defer qrFile.Close()
 // 将二维码文件接码成图片
 img, _, err := image.Decode(qrFile)
 if err != nil {
 log.Fatalf("image decode error %s", err.Error())
 return
 }
 // 获取二维码的宽高
 width, height := img.Bounds().Max.X, img.Bounds().Max.Y
 // 打开要填充的图片
 bgFile, err := os.Open("bg/7.jpg")
 if err != nil {
 log.Fatalf("打开填充图失败 %s", err.Error())
 return
 }
 defer bgFile.Close()
 // 将填充图解码成png图片
 bgImg, _, err := image.Decode(bgFile)
 if err != nil {
 log.Fatalf("填充图解码失败 %s", err.Error())
 return
 }
 // 获取填充图的宽高
 bgWidth, bgHeight := bgImg.Bounds().Max.X, bgImg.Bounds().Max.Y
 // 检测二维码和填充图宽高是否一致
 if width != bgWidth || height != bgHeight {
 // 如果不一致将填充图剪裁
 bgImg = ImageResize(bgImg, width, height)
 }
 // 开始填充二维码
 for y := 0; y < img.Bounds().Max.X; y++ {
 for x := 0; x < img.Bounds().Max.X; x++ {
 qrImgColor := img.At(x, y)
 // 检测图片颜色 如果rgb值是 255 255 255 255 则像素点为白色 跳过
 // 如果rgba值是 0 0 0 0 则为透明色 跳过
 switch img.(type) {
 case *image.NRGBA:
 c := qrImgColor.(color.NRGBA)
 if (c.R == 0 && c.G == 0 && c.B == 0 && c.A == 0) || (c.R == 255 && c.G == 255 && c.B == 255 && c.A == 255) {
 continue
 }
 case *image.RGBA:
 c := qrImgColor.(color.RGBA)
 if (c.R == 0 && c.G == 0 && c.B == 0 && c.A == 0) || (c.R == 255 && c.G == 255 && c.B == 255 && c.A == 255) {
 continue
 }
 }
 // 获取要填充的图片的颜色
 bgImgColor := bgImg.At(x, y)
 
 // 填充颜色
 switch bgImg.(type) {
 case *image.RGBA64:
 c := bgImgColor.(color.RGBA64)
 img.(draw.Image).Set(x, y, color.RGBA64{R: c.R, G: c.G, B: c.B, A: c.A})
 case *image.NRGBA:
 c := bgImgColor.(color.NRGBA)
 img.(draw.Image).Set(x, y, color.NRGBA{R: c.R, G: c.G, B: c.B, A: c.A})
 case *image.RGBA:
 c := bgImgColor.(color.RGBA)
 img.(draw.Image).Set(x, y, color.RGBA{R: c.R, G: c.G, B: c.B, A: c.A})
 case *image.YCbCr:
 c := bgImgColor.(color.YCbCr)
 img.(draw.Image).Set(x, y, color.YCbCr{Y: c.Y, Cb: c.Cb, Cr: c.Cr})
 default:
 fmt.Println("error")
 }
 }
 }
 filename := fmt.Sprintf("%s.png", time.Now().Format("20060102150405"))
 // 写入文件
 outFile, err := os.Create(filename)
 if err != nil {
 log.Fatal(err)
 }
 defer outFile.Close()
 _ = png.Encode(outFile, img)
}
func ImageResize(src image.Image, w, h int) image.Image {
 return resize.Resize(uint(w), uint(h), src, resize.Lanczos3)
}

注意

1 尽量用png的二维码和填充图
2 案例中png和jpg gif图片都可以填充 其他格式的图片自己加就行了

代码地址

https://github.com/lihaotian0607/qr

其他

另外附上封装好的
https://github.com/lihaotian0607/qrcode

生成普通二维码

var qr, err = qrcode.New("https://www.xxx.com/", qrcode.Highest)

设置头像

 qr.SetAvatar(&qrcode.Avatar{
 Src: "../static/1.jpg",
 Width: 60,
 Height: 60,
 Round: 10,
 })

设置背景图

qr.SetBackground(&qrcode.Background{
 Src: "../static/3.png",
 X: 70,
 Y: 55,
 Width: 270,
 Height: 270,
 })

设置前景图

qr.SetForeground("../static/2.png")

写入文件

img, err := qr.Generate(300)
 if err != nil {
 log.Fatal(err.Error())
 return
 }
 file, err := os.Create("out.png")
 if err != nil {
 log.Fatalf("创建文件失败 %s", err.Error())
 return
 }
 err = png.Encode(file, img)
 if err != nil {
 log.Fatalf("文件写入失败 %s", err.Error())
 }

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

本文来自:简书

感谢作者:hi李昊天

查看原文:golang 生成个性二维码

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

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

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏