第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

【Go語(yǔ)言繪圖】 微信公眾號(hào)文章封面圖生成

標(biāo)簽:
Go

想法来源

每次写文章都得花点时间找图,有点点麻烦,(其实就是懒。。。)。而且翻了翻之前的文章配图,大概是这个样子。

图片描述

emmm,风格还挺统一的。但身为正义凛然的公众号博主,老是用这样图,会有些图文不符,也不符合我这正襟危坐的人物形象,而且,做为一名程序猿,能用代码解决的事情,自然要用代码来解决。
最近看到有些技术类公众号,都使用了统一的图片模版,比如这样:

图片描述

左边放上logo,右边放字,简约大气。于是,想着自己也整一个。

图片描述

图片分析

要如何生成这样一张图呢,我们来简单来分析一下。

最底层是一张纯色的底图,这个不难,之前已经介绍过如何绘制纯色底图了,具体颜色可以用工具吸色看看。

第二层是文字,在前面的文章中,已经介绍过如何绘制文字,在这里刚好能用上。

第三层是logo,还没有介绍过将一张图覆盖在另一张图上的操作,本文会对此进行讲解。

这里还需要注意的就是文字跟logo的区域,在绘制时,需要将文本框和图片框的位置计算好,这个可以使用 Sketch 工具来完成。

图片描述
图片描述

图片描述

这样就得到了Logo和文字位置的具体信息。

接下来就可以开始写代码了

代码编写

首先,我们先绘制一个纯色的背景。RGB色值为:(63, 64, 87),底图的宽和高通过 Sketch 工具测出分别为 1050和442。

import (
	"github.com/fogleman/gg"
	"testing"
)

func TestDrawWxPic(t *testing.T){
	weight := 1050
	height := 442
	dc := gg.NewContext(weight, height)
	dc.SetRGB255(63, 64, 87)
	dc.Clear()
	dc.SavePNG("out.png")
}

输出图片如下:

图片描述

然后来绘制第二层的文字:

import (
	"github.com/fogleman/gg"
	"golang.org/x/image/font"
	"golang.org/x/image/font/opentype"
	"io/ioutil"
	"testing"
)

func TestDrawWxPic(t *testing.T){
	width := 1050
	height := 442
	dc := gg.NewContext(width, height)
	dc.SetRGB255(63, 64, 87)
	dc.Clear()

	fontFilePath := "/Users/bytedance/Downloads/FangZhengKaiTiJianTi.TTF"
	fontFace, err := getOpenTypeFontFace(fontFilePath, 76, 72)
	if err != nil {
		panic(err)
	}
	dc.SetFontFace(*fontFace)
	dc.SetRGB255(238, 241, 247)

	// 文本框最大宽度
	maxWordsWidth := 660.0
	x := 645.0
	y := 224.0
	dc.DrawStringWrapped("高并发的秘密武器 epoll 机制", x, y, 0.5, 0.6, maxWordsWidth, 1.1, gg.AlignCenter)
	dc.SavePNG("out.png")
}

func getOpenTypeFontFace(fontFilePath string, fontSize, dpi float64)(*font.Face, error){
	fontData, fontFileReadErr := ioutil.ReadFile(fontFilePath)
	if fontFileReadErr != nil {
		returnnil, fontFileReadErr
	}
	otfFont, parseErr := opentype.Parse(fontData)
	if parseErr != nil {
		returnnil, parseErr
	}
	otfFace, newFaceErr := opentype.NewFace(otfFont, &opentype.FaceOptions{
		Size: fontSize,
		DPI:  dpi,
	})
	if newFaceErr != nil {
		returnnil, newFaceErr
	}
	return &otfFace, nil
}

DrawStringWrapped 方法已经在之前的文章中介绍过了,这里就不缀述了,文本框的位置可以通过 (x,y,ax,ay) 这四个参数来调整。
输出效果如下:

图片描述

字体不太一样,位置是差不多了。

最后来把logo拼上去:

import (
	"github.com/disintegration/imaging"
	"github.com/fogleman/gg"
	"golang.org/x/image/font"
	"golang.org/x/image/font/opentype"
	"io/ioutil"
	"testing"
)

func TestDrawWxPic(t *testing.T){
	...
	dc.DrawStringWrapped("高并发的秘密武器 epoll 机制", x, y, 0.5, 0.6, maxWordsWidth, 1.1, gg.AlignCenter)

	//开始压缩图片
	src, openErr := imaging.Open("logo.png")
	if openErr != nil {
		panic(openErr)
	}
	src = imaging.Resize(src, 240, 240, imaging.Lanczos)
	dc.DrawImageAnchored(src, 182, 220, 0.5, 0.5)
	dc.SavePNG("out.png")
}

fogleman/gg 包不支持对图片使用 resize 的操作,因此这里引入了一个新包,github.com/disintegration/imaging。效果如下:

图片描述

emm,看起来颜色有些不谐调,改一下背景色,然后放大一下logo试试:

图片描述

嗯,这样就好多了,把这段代码封装成方法,传入标题和文件保存位置,即可一键生成封面图。
完整代码如下:

import (
	"github.com/disintegration/imaging"
	"github.com/fogleman/gg"
	"golang.org/x/image/font"
	"golang.org/x/image/font/opentype"
	"io/ioutil"
	"testing"
)

func TestDrawWxPic(t *testing.T){
	generateWxImage("微信公众号封面图\n一键生成", "result")
}

func generateWxImage(title string, savingFileName string) {
	width := 1050
	height := 442
	dc := gg.NewContext(width, height)
	dc.SetRGB255(47, 54, 66)
	dc.Clear()

	fontFilePath := "FangZhengKaiTiJianTi.TTF"
	fontFace, err := getOpenTypeFontFace(fontFilePath, 76, 72)
	if err != nil {
		panic(err)
	}
	dc.SetFontFace(*fontFace)
	dc.SetRGB255(238, 241, 247)

	// 文本框最大宽度
	maxWordsWidth := 660.0
	x := 665.0
	y := 224.0
	dc.DrawStringWrapped(title, x, y, 0.5, 0.6, maxWordsWidth, 1.1, gg.AlignCenter)

	//开始压缩图片
	src, openErr := imaging.Open("logo.png")
	if openErr != nil {
		panic(openErr)
	}
	src = imaging.Resize(src, 360, 360, imaging.Lanczos)

	dc.DrawImageAnchored(src, 182, 220, 0.5, 0.5)

	dc.SavePNG(savingFileName + ".png")
}

func getOpenTypeFontFace(fontFilePath string, fontSize, dpi float64)(*font.Face, error){
	fontData, fontFileReadErr := ioutil.ReadFile(fontFilePath)
	if fontFileReadErr != nil {
		returnnil, fontFileReadErr
	}
	otfFont, parseErr := opentype.Parse(fontData)
	if parseErr != nil {
		returnnil, parseErr
	}
	otfFace, newFaceErr := opentype.NewFace(otfFont, &opentype.FaceOptions{
		Size: fontSize,
		DPI:  dpi,
	})
	if newFaceErr != nil {
		returnnil, newFaceErr
	}
	return &otfFace, nil
}

小结

回顾一下整个过程,其实只要想清楚最终想要的效果,然后把步骤拆解开来,代码其实写起来并不复杂,重要的还是逻辑,至于类似于如何实现图片裁剪、文字拼接、图片缩放,这些通常都有现成的库可以拿来就用。
当然,如果感兴趣也可以深入研究其中的实现原理。就像前面所说,了解这些工具,可以增加手中的牌,遇到问题时自然更加左右逢源。
最近的大部分时间都花在了健身上,很长时间都没有好好写博客了,接下来得好好写文章了,光有输入确实还不够,用输出反推输入,会更加有的放矢。

點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺(jué)得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
JAVA開(kāi)發(fā)工程師
手記
粉絲
1.8萬(wàn)
獲贊與收藏
2564

關(guān)注作者,訂閱最新文章

閱讀免費(fèi)教程

  • 推薦
  • 1
  • 收藏
  • 共同學(xué)習(xí),寫(xiě)下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說(shuō)多少就多少
贊賞金額會(huì)直接到老師賬戶(hù)
支付方式
打開(kāi)微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專(zhuān)欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢(xún)優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消