golang 生成二维码名片 海报这里写自定义目录标题
golang 生成二维码名片 海报
根据用户自定生成个人名片,海报。可以指定海报宽,高。指定文字大小等
使用
var text = []string{
"地址:程序猿天堂",
"姓名:猿职场",
"电话:100098",
}
poster("dst.jpg",text, "https://baidu.com", "./logo.png", 0, 0)
生成效果
实现代码
/**
* @title: 生成海报
* @intro: 生成海报
* @user: 猿职场
* @date: 2022/10/12
**/
package main
import (
"fmt"
"github.com/golang/freetype"
"github.com/nfnt/resize"
"github.com/skip2/go-qrcode"
"io/ioutil"
"unicode/utf8"
"image"
"image/draw"
"image/png"
"log"
"os"
)
const (
DPI = 72 // 设置屏幕分辨率
FONT_FILE = "simsun.ttf" // 设置字体
FONT_SIZE = 12 // 设置字体大小
SPACING = 1.5 // 设置文字行高
OFFSET = 20 // 设置图文间距
QR_SIZE = 150 // 设置二维码大小
)
func main() {
var text = []string{
"地址:程序猿天堂",
"姓名:猿职场",
"电话:100098",
}
poster("dst.jpg",text, "https://baidu.com", "./logo.png", 0, 0)
}
/**
* @name: 生成海报
* @intro: 生成名片,海报等
* @param: imageName:生成图片名称 content:生成文字 qr:二维码 logo:二维码logo imgWidth:图片宽度 imgHeight: 图片高度
* @return: err
* @user: 猿职场
* @date: 2022/10/12
**/
func poster(imageName string,content []string,qr string, logo string, imgWidth int, imgHeight int) error {
file, err := os.Create(imageName)
if err != nil {
fmt.Println(err)
return err
}
defer file.Close()
// 生成二维码
img := qrcodeImg(qr, logo)
//尺寸
if imgWidth > 0 && imgHeight > 0 {
rate := float64(imgWidth) / float64(img.Bounds().Max.X)
img = resize.Resize(uint(float64(img.Bounds().Max.X) * rate), uint(float64(img.Bounds().Max.Y) * rate), img, resize.Lanczos3)
}
fontBytes, err := ioutil.ReadFile(FONT_FILE)
if err != nil {
log.Println(err)
return err
}
f, err := freetype.ParseFont(fontBytes)
if err != nil {
log.Println(err)
return err
}
// 写文字
c := freetype.NewContext()
c.SetDPI(DPI)
c.SetFont(f)
c.SetFontSize(FONT_SIZE)
strLen := 0
strRowNum := 0
for _, str := range content {
strRowNum++
strLenTmp := utf8.RuneCountInString(str)
if strLen < strLenTmp {
strLen = strLenTmp
}
}
strWidth := int(c.PointToFixed(FONT_SIZE)>>6) * strLen
strHeight := int(c.PointToFixed(FONT_SIZE*SPACING)>>6) * strRowNum
fmt.Println("str画布大小:", strWidth, strHeight)
// 计算高度
width := strWidth
if width < img.Bounds().Max.X {
width = img.Bounds().Max.X
}
width += OFFSET
height := strHeight + img.Bounds().Max.Y + OFFSET
if imgWidth > 0 && imgHeight > 0 {
width = imgWidth
height = imgHeight
}
// 画背景
bg := image.White
jpg := image.NewRGBA(image.Rect(0, 0, width, height))
fmt.Println("width:", width, height)
draw.Draw(jpg, jpg.Bounds(), bg, image.Pt(0, 0), draw.Over)
// 添加图片
offset := image.Pt((jpg.Bounds().Max.X-img.Bounds().Max.X)/2, 10)
draw.Draw(jpg, img.Bounds().Add(offset), img, img.Bounds().Min, draw.Src) //截取图片的一部分
// 文字创建
c.SetSrc(image.Black)
c.SetClip(jpg.Bounds())
c.SetDst(jpg)
pt := freetype.Pt((jpg.Bounds().Max.X-strWidth)/2, img.Bounds().Max.Y+20)
for _, s := range content {
_, err = c.DrawString(s, pt)
if err != nil {
log.Println(err)
return err
}
pt.Y += c.PointToFixed(FONT_SIZE * SPACING)
}
err = png.Encode(file, jpg)
return err
}
/**
* @name: 生成二维码
* @intro:
* @param: content:二维码 logo:二维码logo
* @return: image.Image
* @user: 猿职场
* @date: 2022/10/12
**/
func qrcodeImg(content, logo string) image.Image {
code, err := qrcode.New(content, qrcode.Medium)
if err != nil {
return nil
}
qrcodeImg := code.Image(QR_SIZE)
outImg := image.NewRGBA(qrcodeImg.Bounds())
if logo != "" {
logoFile, err := os.Open(logo)
if err != nil {
fmt.Println("打开logo文件错误:", logo)
return outImg
}
logoImg, _, err := image.Decode(logoFile)
logoImg = resize.Resize(uint(20), uint(20), logoImg, resize.Lanczos3)
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)
}
return outImg
}