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
    }
    
  • 相关阅读:
    在Xsheel Linux上安装nodejs和npm
    判断js中的数据类型的几种方法
    Sequelize 中文API文档-1. 快速入门、Sequelize类
    php中 ob_start()有什么作用
    PHP错误类型及屏蔽方法
    ajax对象的获取及其常用属性
    linux工作笔记
    Redis和Memcached的区别
    MySQL架构
    Http协议三次握手过程
  • 原文地址:https://www.cnblogs.com/Csir/p/9372588.html
Copyright © 2011-2022 走看看