生成二维码

Posted csir

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了生成二维码相关的知识,希望对你有一定的参考价值。

package main

import (
    "bytes"
    "encoding/base64"
    "encoding/json"
    "fmt"
    "image"
    "image/color"
    "image/draw"
    "image/gif"
    "image/jpeg"
    "image/png"
    "io/ioutil"
    "log"
    "net/http"

    "code.google.com/p/rsc/qr"
    "code.google.com/p/rsc/qr/web/resize"
    "github.com/golang/freetype"
    "github.com/golang/freetype/truetype"
    "golang.org/x/image/bmp"
    "golang.org/x/image/font"
    "golang.org/x/image/math/fixed"
)

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)+0.5, float64(y-c.p.Y)+0.5, float64(c.r)
    if xx*xx+yy*yy < rr*rr {
        return color.Alpha{255}
    }
    return color.Alpha{0}
}

var (
    // bgImage 漂亮的背景
    bgImage = getNetImage("http://olcd71ai5.bkt.clouddn.com/qr/bg.png")

    // fontFile 字体文件
    fontFile = "config/Dengl.ttf"

    // fontSize 字体尺寸
    fontSize float64 = 18

    // fontDPI 屏幕每英寸的分辨率
    fontDPI float64 = 72

    // font 字体
    fontType *truetype.Font
)

func init() {
    fontBytes, err := ioutil.ReadFile(fontFile)
    if err != nil {
        panic(err)
    }
    fontType, err = freetype.ParseFont(fontBytes)
    if err != nil {
        panic(err)
    }
}

func main() {
    http.HandleFunc("/qr", qrImage)
    fmt.Println(http.ListenAndServe(":8080", nil))
}

func qrImage(w http.ResponseWriter, req *http.Request) {
    content := req.FormValue("data")
    data, err := base64.StdEncoding.DecodeString(content)
    if err != nil {
        log.Println(err)
        return
    }

    v := struct {
        URL      string `json:"url"`
        HeadURL  string `json:"headurl"`
        NickName string `json:"nickname"`
    }{}
    json.Unmarshal(data, &v)
    sx, sy, width := 110, 915, 120
    qrCode, _ := qr.Encode(v.URL, qr.L)
    pngData := qrCode.PNG()
    imgQrPng, _ := png.Decode(bytes.NewReader(pngData))
    imgQrPng = resize.Resample(imgQrPng, imgQrPng.Bounds(), width, width)
    qrBounds := imgQrPng.Bounds()
    qrDx := qrBounds.Dx()
    qrDy := qrBounds.Dy()

    img := image.NewRGBA(bgImage.Bounds())
    draw.Draw(img, bgImage.Bounds(), bgImage, image.Pt(0, 0), draw.Src)

    for x := 0; x < qrDx; x++ {
        for y := 0; y < qrDy; y++ {
            qrColor := imgQrPng.At(x, y)
            r, g, b, _ := qrColor.RGBA()
            if r == 0 || g == 0 || b == 0 {
                img.Set(sx+x, sy+y, qrColor)
            }
        }
    }

    if v.HeadURL != "" {
        headImage := getNetImage(v.HeadURL)
        headImage = resize.Resample(headImage, headImage.Bounds(), 100, 100)
        sp := image.Pt(250, 80)
        rect := headImage.Bounds().Add(sp)
        draw.DrawMask(img, rect, headImage, image.ZP, &circle{image.Pt(50, 50), 50}, image.ZP, draw.Over)
    }

    if v.NickName != "" {
        d := &font.Drawer{
            Dst: img,
            Src: image.NewUniform(color.RGBA{0xff, 0x00, 0x00, 0xff}),
            Face: truetype.NewFace(fontType, &truetype.Options{
                Size:    fontSize,
                DPI:     fontDPI,
                Hinting: font.HintingNone,
            }),
        }

        d.Dot = fixed.Point26_6{
            X: (fixed.I(600) - d.MeasureString(v.NickName)) / 2,
            Y: fixed.I(205),
        }
        d.DrawString(v.NickName)
    }

    w.Header().Set("Content-Type", "image/jpeg")
    jpeg.Encode(w, img, &jpeg.Options{Quality: 90})
}

func getNetImage(url string) image.Image {
    resp, err := http.Get(url)
    if err != nil {
        log.Println(err)
        return image.NewNRGBA(image.Rect(0, 0, 600, 400))
    }
    defer resp.Body.Close()
    data, _ := ioutil.ReadAll(resp.Body)
    contentType := http.DetectContentType(data)
    var imgBG image.Image
    if contentType == "image/png" {
        imgBG, err = png.Decode(bytes.NewReader(data))
    } else if contentType == "image/jpeg" {
        imgBG, err = jpeg.Decode(bytes.NewReader(data))
    } else if contentType == "image/gif" {
        imgBG, err = gif.Decode(bytes.NewReader(data))
    } else if contentType == "image/bmp" {
        imgBG, err = bmp.Decode(bytes.NewReader(data))
    }
    if err != nil {
        log.Println(err)
        return image.NewNRGBA(image.Rect(0, 0, 600, 400))
    }
    return imgBG
}

以上是关于生成二维码的主要内容,如果未能解决你的问题,请参考以下文章

postman 自动生成 curl 代码片段

leetcode_1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold_[二维前缀和](代码片段

Apollo Codegen 没有找到生成代码的操作或片段

前端开发工具vscode如何快速生成代码片段

前端开发工具vscode如何快速生成代码片段

vscode代码片段生成vue模板