千里皓月

V1

2022/10/01阅读:14主题:橙心

蹭个国庆热度,实现微信渐变国旗头像

图片获取方式

又到了一年一度的国庆佳节,这次我们也来蹭一下热度,给微信头像加上渐变国旗,效果类似下图:

生成方式非常简单,只需要在本公众号后台,发送图片就可以生成对应的国旗头像。

怎么样,比起需要关注其他公众号、下载工具等,是不是操作方便了很多。然而,在测试的时候...

属实是给他们玩坏了...

实现方式

  • 图片合并
  • 微信公众号开发

图片合并

golang 对图片合并,使用的是 golang.org/x/image/draw 这个组件

  • 首先,准备一张 guoqi.png 放到服务器中,并读取
  • 读取上传的微信头像,并设置成 1000*1000 像素的背景。因为公众号后台的处理速度超过五秒,则会提示”服务出现故障“,为防止用户上传过大的图片导致处理速度较慢,因此固定像素处理
  • 生成与背景图片相同大小的模板,并将背景图片覆盖在模板上。
  • guoqi.png 覆盖在模板上
  • 保存图片
open, err := os.Open("./guoqi.png")
if err != nil {
    return "", err
}
defer open.Close()

templateFileImage, err := png.Decode(open)
if err != nil {
    return "", err
}

imageRes, err := useHttp.Get(path)
if err != nil || imageRes.StatusCode != 200 {
    return "", err
}
defer imageRes.Body.Close()

backImg, err := jpeg.Decode(imageRes.Body)

backImg = resize.Resize(10001000, backImg, resize.NearestNeighbor)

newTemplateImage := image.NewRGBA(backImg.Bounds())
draw.Draw(newTemplateImage, backImg.Bounds(), backImg, backImg.Bounds().Min, draw.Over)
draw.Draw(newTemplateImage, newTemplateImage.Bounds().Add(image.Pt(00)),
          templateFileImage, templateFileImage.Bounds().Min, draw.Over)

retPath := fmt.Sprintf("./face/%s.png", strconv.FormatInt(time.Now().UnixNano(), 10))
dstFile, err := os.Create(retPath)
if err != nil {
    return "", err
}
defer dstFile.Close()
err = png.Encode(dstFile, newTemplateImage)
if err != nil {
    return "", err
}
return retPath, nil

微信公众号后台开发

原本我以为开发微信公众号后台是需要收费的,后来发现只要是公众号管理员都可以实现,只需要有一台服务器即可。关于服务器的购买,阿里云或腾讯云皆可,新用户在腾讯云几十块就可以买到一年的2核2G的服务器,十分划算。

申请成为开发者。

在微信公众号后台,设置与开发->基本配置中,填写对应的 url 与 token,url 是服务器地址,在点击保存提交后,公众号后台会发送请求到这个地址进行 token 和秘钥的验证,以确保是本人在进行开发。

后台会向 url 发送四个参数

  • signature:微信加密签名
  • timestamp:时间戳
  • nonce:随机数
  • echostr:随机字符串

将 token(基本配置中自定义)、timestamp、nonce三个参数进行字典序排序,并拼接成字符串,将获得的字符串与 signature 进行对比,如果通过,则成功建立链接,基本配置保存成功。

golang 代码如下:

token := conf.Token
tmpArr := []string{token, timestamp, nonce}
sort.Strings(tmpArr)
tmpStr := strings.Join(tmpArr, "")
sha1 := utils.SHA1(tmpStr)
fmt.Println(sha1)
fmt.Println(signature)
return sha1 == signature

详细请看官方文档:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html

获取用户发送信息

在成功接入微信公众号后台之后,你的公众号自定义菜单和自动恢复都会被清空初始化,转而通过程序进行管理。

成功接入之后,用户每次发送信息,其实都是向你在基础配置中的 url 发送一次 post 请求,发送的信息会通过 xml 参数传递。

可参考官方文档:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html

目前支持接收的消息有:文本消息、图片消息、语音消息、视频消息以及小视频消息。

图片消息的 xml 格式如下图所示:

可以看到,图片是 PicUrl 字段 ,后台会自动生成 url 格式发给我们,我们只要通过链接就可以获取图片了。

向用户发送图片

当我们拼接完成图片之后,就需要向用户发送图片了。然而,发送图片并不是直接通过 url 的方式,而是需要先将图片上传至素材库,再将素材库的媒体 id 发送回后台。

我们采用上传临时素材的方式,临时素材只保存三天,不会对素材库的内存产生影响,文档链接:https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html

jsonbody, err := http.FileUploadRequest(fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=image", conf.AssesToken),
 map[string]string{}, "media", face)
if err != nil {
    return "", err
}

fmt.Println(string(jsonbody))

type WxImage struct {
    Type      string  `json:"type"`
    MediaId   string  `json:"media_id"`
    CreatedAt int     `json:"created_at"`
}
var result WxImage
json.Unmarshal(jsonbody, &result)
return result.MediaId, nil

到这里,一个完整的向公众号发送图片并返回添加过期图片的头像已经完成啦!

这里,还有一个彩蛋喔,在公众号后台回复毒鸡汤,看看你能收获到怎样的毒吧!

分类:

后端

标签:

后端

作者介绍

千里皓月
V1