From 71b3fe8bbf4da2b649d18f7dfed3f000dc116593 Mon Sep 17 00:00:00 2001 From: lixiangwuxian Date: Fri, 1 Nov 2024 22:35:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=96=9C=E6=8A=A5=E4=B8=8D=E8=A6=81?= =?UTF-8?q?=E6=B1=82=E4=BF=9D=E8=AF=81=E5=90=8C=E4=B8=80=E6=9D=A1=E6=B6=88?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + go.mod | 2 +- handler/xibao/xibao.go | 35 +++++++++++++++++++++++++----- service/xibao/image_gen.go | 44 +++++++++++++++++++++++++++++++++----- 4 files changed, 71 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index abb8764..8c004f8 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ config.yml tmp/ __debug* Dockerfile +resource/emoji.ttf diff --git a/go.mod b/go.mod index 00c8468..4dbba47 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/mattn/go-sqlite3 v1.14.23 github.com/sashabaranov/go-openai v1.30.3 golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c + golang.org/x/image v0.21.0 golang.org/x/net v0.30.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -69,7 +70,6 @@ require ( go.opentelemetry.io/otel/trace v1.31.0 // indirect golang.org/x/arch v0.8.0 // indirect golang.org/x/crypto v0.28.0 // indirect - golang.org/x/image v0.21.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.7.0 // indirect diff --git a/handler/xibao/xibao.go b/handler/xibao/xibao.go index 14bcc50..b7808f3 100644 --- a/handler/xibao/xibao.go +++ b/handler/xibao/xibao.go @@ -21,13 +21,13 @@ func init() { func xiBao(msg model.Message) (reply model.Reply) { fileName := uuid.New().String() filePath := "./tmp/" + fileName + ".png" - re := regexp.MustCompile(`\s+`) tokens := re.Split(msg.RawMsg, 2) if len(tokens) < 2 { + handler.RegisterLiveHandler(msg.GroupInfo.GroupId, msg.UserId, xiBaoTemp) return model.Reply{ - ReplyMsg: "参数不足, 请使用\"喜报 [内容]\"生成喜报图片", - ReferOriginMsg: true, + ReplyMsg: "", + ReferOriginMsg: false, FromMsg: msg, } } @@ -39,15 +39,28 @@ func xiBao(msg model.Message) (reply model.Reply) { } } +func xiBaoTemp(msg model.Message) (reply model.Reply, isTrigger bool) { + fileName := uuid.New().String() + filePath := "./tmp/" + fileName + ".png" + xibao.GenerateCongratulationImage(msg.RawMsg, "./resource/xibao_background.png", filePath, true) + handler.UnRegisterLiveHandler(msg.GroupInfo.GroupId, msg.UserId) + return model.Reply{ + ReplyMsg: fmt.Sprintf("[CQ:image,file=file:///root/qqbot/tmp/%s]", fileName+".png"), + ReferOriginMsg: true, + FromMsg: msg, + }, true +} + func beiBao(msg model.Message) (reply model.Reply) { fileName := uuid.New().String() filePath := "./tmp/" + fileName + ".png" re := regexp.MustCompile(`\s+`) tokens := re.Split(msg.RawMsg, 2) if len(tokens) < 2 { + handler.RegisterLiveHandler(msg.GroupInfo.GroupId, msg.UserId, beiBaoTemp) return model.Reply{ - ReplyMsg: "参数不足, 请使用\"悲报 [内容]\"生成悲报图片", - ReferOriginMsg: true, + ReplyMsg: "", + ReferOriginMsg: false, FromMsg: msg, } } @@ -58,3 +71,15 @@ func beiBao(msg model.Message) (reply model.Reply) { FromMsg: msg, } } + +func beiBaoTemp(msg model.Message) (reply model.Reply, isTrigger bool) { + fileName := uuid.New().String() + filePath := "./tmp/" + fileName + ".png" + xibao.GenerateCongratulationImage(msg.RawMsg, "./resource/beibao_background.png", filePath, false) + handler.UnRegisterLiveHandler(msg.GroupInfo.GroupId, msg.UserId) + return model.Reply{ + ReplyMsg: fmt.Sprintf("[CQ:image,file=file:///root/qqbot/tmp/%s]", fileName+".png"), + ReferOriginMsg: true, + FromMsg: msg, + }, true +} diff --git a/service/xibao/image_gen.go b/service/xibao/image_gen.go index 086ff0c..f3482cf 100644 --- a/service/xibao/image_gen.go +++ b/service/xibao/image_gen.go @@ -1,14 +1,15 @@ package xibao import ( - "fmt" "log" + "os" "strings" "git.lxtend.com/qqbot/model" "git.lxtend.com/qqbot/util" "github.com/fogleman/gg" "github.com/google/uuid" + "golang.org/x/image/font/opentype" ) func GenerateCongratulationImage(text string, inputFile, outputFile string, isGood bool) { @@ -51,8 +52,8 @@ func GenerateCongratulationImage(text string, inputFile, outputFile string, isGo scaleFactor := 1.0 // 根据高度比例进行缩放 - if float64(heightC) > float64(height)/1.5 { - scaleFactor = (float64(height) / 1.5) / float64(heightC) + if float64(heightC) > float64(height)/1.8 { + scaleFactor = (float64(height) / 1.8) / float64(heightC) } // 根据宽度比例进行缩放 @@ -64,10 +65,10 @@ func GenerateCongratulationImage(text string, inputFile, outputFile string, isGo if heightC < height/5 && widthC < width/4 { if float64(widthC)*(float64(height)/5)/float64(heightC) > float64(width/4) { scaleFactor = (float64(height) / 5) / float64(heightC) - log.Print(fmt.Sprintf("图片高度过小,已缩放至高度的 %f 倍", scaleFactor)) + // log.Print(fmt.Sprintf("图片高度过小,已缩放至高度的 %f 倍", scaleFactor)) } else { scaleFactor = (float64(width) / 4) / float64(widthC) - log.Print(fmt.Sprintf("图片宽度过小,已缩放至宽度的 %f 倍", scaleFactor)) + // log.Print(fmt.Sprintf("图片宽度过小,已缩放至宽度的 %f 倍", scaleFactor)) } } @@ -90,10 +91,43 @@ func GenerateCongratulationImage(text string, inputFile, outputFile string, isGo } // 设置字体和大小,字体文件需要自备,放在合适的路径 + // if err := dc.LoadFontFace("./resource/emoji.ttf", 96); err != nil { + // log.Print("无法加载字体:", err) + // return + // } + fontBytes, err := os.ReadFile("./resource/emoji.ttf") + if err != nil { + log.Print("failed to load font: %v", err) + } + + // 解析字体 + font, err := opentype.Parse(fontBytes) + if err != nil { + log.Print("failed to parse font: %v", err) + } + + // 设置字体大小和 DPI + const fontSize = 48 + const dpi = 72 + + // 创建 font.Face,用于渲染文本 + face, err := opentype.NewFace(font, &opentype.FaceOptions{ + Size: fontSize, + DPI: dpi, + Hinting: 0, + }) + if err != nil { + log.Print("failed to create font face: %v", err) + return + } + + dc.SetFontFace(face) + if err := dc.LoadFontFace("./resource/font.ttf", 96); err != nil { log.Print("无法加载字体:", err) return } + if isGood { // 设置文本颜色为红色 dc.SetRGB(0.8, 0, 0)