前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >3 分钟带你通过 Go 生成宣传海报!

3 分钟带你通过 Go 生成宣传海报!

作者头像
小锟哥哥
发布2022-12-05 14:07:15
1.3K0
发布2022-12-05 14:07:15
举报
文章被收录于专栏:GoLang全栈GoLang全栈

对于公网应用来说,海报功能是非常非常重要的,它不仅能扩大应用的知名度,还能起到营销的作用。

那从技术上讲,海报该怎么去做呢?

大部分应用都会选择前端渲染,比如 canvas 渲染,这是最常见的。当然也有一些应用选择后端生成,两者各有各的好处,也有各自的缺点。

这里我们不去讨论前端怎么渲染,只讲后端怎么生成。

先来看下我们将要完成的效果,这是没有加文字和二维码的图片:

这是加上我们的二维码和汉字的样子:

因为微信不允许使用二维码的图片,所以我给打马赛克了。

一、使用 Go 的 image 库

Go 在处理图形上,并没有其他语言,比如 Java、Python 这些库多。

主要 Go 的发力点并不在上面,但是如果工作需要用到 Go 来做海报,也不是不可以。

首先我们可以看到 Go 的官方包里面也提供了 image 包,可以用它来处理图片。

但是,并不是特别建议新手小白直接用这包来处理图片,那你会触碰到很多底层的知识。

更加建议使用一些别人封装好的库,使用起来会更加便捷顺手。所以这里我们就直接跳过了哈,嘻嘻。

二、github.com/golang/freetype

这里我推荐的第一个库是这个,他相对来说封装得不是那么面目全非,所以代码量会多一些,但是他比较能熟悉 image 标准库的使用。

1、安装

这个库的官网地址:https://github.com/golang/freetype

安装命令:

代码语言:javascript
复制
go get github.com/golang/freetype

然后就可以直接使用了,不过后面我们会用到重置图片大小,需要用到另外一个库,这里也可以一起安装下:

代码语言:javascript
复制
go get github.com/nfnt/resize

2、准备材料

在实际开发中,你需要向设计师要两张图,一张是最后的效果图,一张是把需要生成的素材抠掉了的图。

如果里面涉及到自定义字体的还得让他们提供字体给我们。

3、上代码

首先来看下我的文件结构:

  • cmd 是我的入口文件
  • public 素材这些我都放这下面了
    • fonts 这里面我放的是我们的自定义字体
    • image 这里我放了两张图,bg.png 背景图 和 wx.png 二维码图。

接下来直接上代码:

代码语言:javascript
复制
package main

import (
 "bytes"
 "fmt"
 "github.com/golang/freetype"
 "github.com/golang/freetype/truetype"
 "github.com/nfnt/resize"
 "image"
 "image/draw"
 "image/jpeg"
 "image/png"
 "io"
 "io/ioutil"
 "log"
 "net/http"
 "os"
 "strings"
)

var (
 fontKai *truetype.Font // 字体
)

func main() {

 // 根据路径打开模板文件
 templateFile, err := os.Open("./public/image/bg.png")
 if err != nil {
  panic(err)
 }
 defer templateFile.Close()
 // 解码
 templateFileImage, err := png.Decode(templateFile)
 if err != nil {
  panic(err)
 }
 // 新建一张和模板文件一样大小的画布
 newTemplateImage := image.NewRGBA(templateFileImage.Bounds())
 // 将模板图片画到新建的画布上
 draw.Draw(newTemplateImage, templateFileImage.Bounds(), templateFileImage, templateFileImage.Bounds().Min, draw.Over)

 // 加载字体文件  这里我们加载两种字体文件
 fontKai, err = loadFont("./public/fonts/kz_wyzt.ttf")
 if err != nil {
  log.Panicln(err.Error())
  return
 }

 // 向图片中写入文字
 // 在写入之前有一些准备工作
 content := freetype.NewContext()
 content.SetClip(newTemplateImage.Bounds())
 content.SetDst(newTemplateImage)
 // 设置字体颜色
 content.SetSrc(image.White)
 // 设置字体分辨率
 content.SetDPI(72)
 // 设置字体大小
 content.SetFontSize(40)
 // 设置字体样式,就是我们上面加载的字体
 content.SetFont(fontKai)
 //  正式写入文字
 // 参数1:要写入的文字
 // 参数2:文字坐标
 content.DrawString("电话:13800008888 地址:xxx_xxx_xxx 商铺", freetype.Pt(151, 2100))

 // 读取二维码图片
 erCodeTemplateFile, err := os.Open("./public/image/wx.png")
 if err != nil {
  panic(err)
 }
 defer templateFile.Close()
 // 解码
 imageData, err := png.Decode(erCodeTemplateFile)
 if err != nil {
  panic(err)
 }
 //   2、重新调整要粘贴图片尺寸
 imageData = resize.Resize(300, 300, imageData, resize.Lanczos3)
 //  粘贴缩略图
 draw.Draw(newTemplateImage,
  newTemplateImage.Bounds().Add(image.Pt(1200, 1800)),
  imageData,
  imageData.Bounds().Min,
  draw.Over)
 // 保存图片
 saveFile(newTemplateImage)
}

// 根据路径加载字体文件
// path 字体的路径
func loadFont(path string) (font *truetype.Font, err error) {
 var fontBytes []byte
 fontBytes, err = ioutil.ReadFile(path) // 读取字体文件
 if err != nil {
  err = fmt.Errorf("加载字体文件出错:%s", err.Error())
  return
 }
 font, err = freetype.ParseFont(fontBytes) // 解析字体文件
 if err != nil {
  err = fmt.Errorf("解析字体文件出错,%s", err.Error())
  return
 }
 return
}

func saveFile(pic *image.RGBA) {
 dstFile, err := os.Create("./public/out/1.png")
 if err != nil {
  fmt.Println(err)
 }
 defer dstFile.Close()
 png.Encode(dstFile, pic)
}

大部分代码都写了注释,如果你有疑问欢迎加我们交流群提问。

三、github.com/hitailang/poster

咱们做事绝对不能一杆子捅到底,还得再准备一个备用库。

前不久一个同学,发消息问我,有个库不能用了,库的 GitHub 都打不开了,问我怎么办?

我能怎么办?这显然是作者关库了呗,不想开放了哇,遇到这种要么找别人下好的给你,要么就直接换库呗,找个替代库。

这个库在封装上比较便利,使用起来比上一个库更加便捷。

1、安装

官方地址:https://github.com/hitailang/poster

安装命令:

代码语言:javascript
复制
go get github.com/hitailang/poster

2、上代码

这个库的官方 GitHub 首页就有详细的 demo,我这里就直接抄过来了:

代码语言:javascript
复制

func main(){
    nullHandler := &handler.NullHandler{}
 ctx := &handler.Context{
  //图片都绘在这个PNG载体上
  PngCarrier: core.NewPNG(0, 0, 750, 1334),
 }
 //绘制背景图
 backgroundHandler := &handler.BackgroundHandler{
  X:    0, // 图片x坐标
  Y:    0, // 图片y坐标
  Path: "./assets/background.png", //图片路径
 }
 //绘制圆形图像
 imageCircleLocalHandler := &handler.ImageCircleLocalHandler{
  X:   30, // 图片x坐标
  Y:   50, // 图片y坐标
        Path: "./assets/reward.png",
  //URL: "http://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTLJT9ncWLPov6rAzn4VCPSC4QoAvdangHRB1JgszqCvffggAysvzpm5MDb72Io4g9YAScHEw7xSWg/132", //图片路径
 }
 //绘制本地图像
 imageLocalHandler := &handler.ImageLocalHandler{
  X:    30, // 图片x坐标
  Y:    400,// 图片y坐标
  Path: "./assets/reward.png", //图片路径
 }

 //绘制二维码
 qrCodeHandler := &handler.QRCodeHandler{
  X:   30, // 二维码x坐标
  Y:   860,// 二维码y坐标
  URL: "https://github.com/hitailang/poster", // 二维码跳转URL地址
 }
 //绘制文字
 textHandler1 := &handler.TextHandler{
  Next:     handler.Next{},
  X:        180, // 文字x坐标
  Y:        105, // 文字y坐标
  Size:     20,  // 文字大小
  R:        255, // 文字颜色RGB值
  G:        241,
  B:        250,
  Text:     "如果觉得这个库对您有用", // 文字内容
  FontPath: "./assets/msyh.ttf",  // 字体文件
 }
 //绘制文字
 textHandler2 := &handler.TextHandler{
  Next:     handler.Next{},
  X:        180,
  Y:        150,
  Size:     22,
  R:        255,
  G:        241,
  B:        250,
  Text:     "请随意赞赏~~",
  FontPath: "./assets/msyh.ttf",
 }
 //结束绘制,把前面的内容合并成一张图片,输出到build目录
 endHandler := &handler.EndHandler{
  Output: "./build/poster_" + xid.New().String() + ".png",
 }

 // 链式调用绘制过程
 nullHandler.
  SetNext(backgroundHandler).
  SetNext(imageCircleLocalHandler).
  SetNext(textHandler1).
  SetNext(textHandler2).
  SetNext(imageLocalHandler).
  SetNext(qrCodeHandler).
  SetNext(endHandler)

 // 开始执行业务
 if err := nullHandler.Run(ctx); err != nil {
  // 异常
  fmt.Println("Fail | Error:" + err.Error())
  return
 }
 // 成功
 fmt.Println("Success")
 return
}

这个库,有两个缺点:

  • 官方的 handler 在绘制图片时,不支持缩放大小,所以如果有需要调整大小的,要么自己实现它的 handler,要么调整图片大小
  • 官方的库在绘制圆形头像时,只支持绘制 png 格式的,否则在剪切时会出现噪点

四、总结

一般开发中很少会让后台绘制海报,毕竟现在大部分海报上都会带有分享者,也就是用户的头像信息啥的,属于专属图片。

所以这种场景大部分都是提供模板给前端绘制。

但是有些场景,比如商品信息,活动信息等,这些统一的一样的,还是有在后端生成的。

你学废了么?

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 GoLang全栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、使用 Go 的 image 库
  • 二、github.com/golang/freetype
    • 1、安装
      • 2、准备材料
        • 3、上代码
        • 三、github.com/hitailang/poster
          • 1、安装
            • 2、上代码
            • 四、总结
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档