zoukankan      html  css  js  c++  java
  • 生成二维码

    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
    }
    
  • 相关阅读:
    yocto/bitbake 学习资源
    QEMU/KVM学习资源
    ubuntu 中创建和删除用户
    git 重命名本地和远程分支
    Ubuntu 上搭建 FTP 服务器
    gdb 常见用法
    git log 显示与特定文件相关的 commit 信息
    基于 qemu system mode 运行 arm 程序
    基于 qemu user mode 运行 aarch64 程序
    checking in(airport)
  • 原文地址:https://www.cnblogs.com/Csir/p/9372588.html
Copyright © 2011-2022 走看看