golang 给微信小程序码图片底部添加文字

作者: adm 分类: go 发布时间: 2023-06-09

由于要做硬件设备的扫码支付,生产的时候为了方便硬件屏幕上确认部署的支付码跟设备匹配,需要在微信小程序码的底部添加上标识文字, 例如设备 ID 之类的。

效果演示

还是三方库好用

https://github.com/fogleman/gg

比用 golang 自带库方便太多了。否则实现添加个文字,脑子爆炸。

字体下载

https://fonts.google.com/

图片上添加文字,就涉及到文本字体的选择,可以在 google fonts 上根据语种需要选择字体。

实现逻辑
先生成一张白色底的大背景图,宽度为原小程序码的宽度,高度加上了文字的高度
然后将原小程序图片复制到背景图的顶部
底部添加文本,居中显示
实现代码

package main

import (
    "image"
    "image/color"
    "image/draw"
    _ "image/jpeg"
    "log"
    "os"

    "github.com/fogleman/gg"
)

func main() {
    filePath := "images/hello.jpg"
    width, err := getImageWidth(filePath)
    if err != nil {
        return
    }
    log.Printf("image width: %+v\n", width)

    GenerateLabel()
}

func GenerateLabel() string{
	filePath := "static/temp/carbon.png"
	/*width, err := getImageWidth(filePath)
	if err != nil {
		return ""
	}
	log.Printf("image width: %+v\n", width)*/
	fmt.Println(total)
        s1:=strconv.FormatFloat(total,'f',3,64)
        name:="我的世界只有你我的世界只有你"
	runName:=[]rune(name) //截取前9位
	s := newImage(filePath, 51,string(runName[0:9]), 36.562)
	if err := orm.Orm.Table(models.Certificate{}.TableName()).Where("id=?", id).Update("carbon_labeling", s).Error; err != nil {
		return ""
	}
	return s
}

func getImageWidth(filePath string) (int, error) {
	reader, err := os.Open(filePath)

	if err != nil {
		log.Println(err.Error())
		return 0, err
	}
	defer reader.Close()

	im, _, err := image.DecodeConfig(reader)
	if err != nil {
		// 如果不 import image/jpeg 会报错:
		// image: unknown format
		log.Println(err.Error())
		return 0, err
	}
	return im.Width, nil
}

func newImage(srcFile string, id int, text string, text2 string) string {
	fontSize := 30
	fontColor := color.RGBA{15, 125, 59, 0xff}
	//background := color.RGBA{0xff, 0xff, 0xff, 0xff}
	reader, err := os.Open(srcFile)

	if err != nil {
		log.Println(err.Error())
		return ""
	}
	defer reader.Close()

	srcImg, _, err := image.Decode(reader)
	if err != nil {
		// 如果不 import image/jpeg 会报错:
		// image: unknown format
		log.Println(err.Error())
		return ""
	}
	width := srcImg.Bounds().Max.X
	//height := width + 2*fontSize
	height := srcImg.Bounds().Max.Y

	upLeft := image.Point{0, 0}
	downRight := image.Point{width, height}

	// 生成背景图
	img := image.NewRGBA(image.Rectangle{upLeft, downRight})
	//background := color.RGBA{0, 0xFF, 0, 0xCC}
	// 设置背景色 (这个如果用 gg 库实现其实更简洁)
	//draw.Draw(img, img.Bounds(), &image.Uniform{background}, image.ZP, draw.Src)
	// 小程序码放顶部
	draw.Draw(img, srcImg.Bounds(), srcImg, image.Point{}, draw.Src)

	// 添加文字
	dc := gg.NewContextForRGBA(img)
	dc.SetColor(fontColor)
	// 设置字体,及字体大小
	if err := dc.LoadFontFace("static/temp/SourceHanSansCN-Bold.ttf", 30); err != nil {
		panic(err)
	}

	textWidth, _ := dc.MeasureString(text)
	//dc.DrawString(text, (float64(width)-textWidth)/2, float64(width+fontSize))
	dc.DrawStringAnchored(text, (float64(width)-textWidth)/2, float64(width+fontSize), -0.4, -19.1)

	textWidth2, _ := dc.MeasureString(text2)
	//dc.DrawString(text, (float64(width)-textWidth)/2, float64(width+fontSize))
	dc.DrawStringAnchored(text2, (float64(width)-textWidth2)/2, float64(width+fontSize), 0, -8.5)

	//f, _ := os.Create("images/result.png")
	//png.Encode(f, img)
	idName := strconv.Itoa(id)
	filePath := fmt.Sprintf("uploads/carbon/%s/", time.Now().Format("200601"))
	_, err = os.Stat(filePath)
	if err != nil {
		if !os.IsExist(err) { // 目录不存在,创建目录
			err := os.MkdirAll(filePath, os.ModePerm)
			if err != nil {
				fmt.Println(err)
				return ""
			}
		}
	}
	dc.SavePNG(filePath + idName + ".png")
	return "/" + filePath + idName + ".png"
}

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!