🐛 修复角色卡导出失败的bug
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"image"
|
||||
_ "image/jpeg"
|
||||
_ "image/png"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -624,10 +625,17 @@ func (cs *CharacterService) ExportCharacterAsPNG(characterID uint, userID *uint)
|
||||
|
||||
// 获取角色头像
|
||||
var img image.Image
|
||||
var loadErr error
|
||||
|
||||
if character.Avatar != "" {
|
||||
// TODO: 从 URL 或文件系统加载头像
|
||||
// 这里暂时创建一个默认图片
|
||||
img = createDefaultAvatar()
|
||||
// 尝试从文件系统或 URL 加载头像
|
||||
img, loadErr = loadAvatarImage(character.Avatar)
|
||||
if loadErr != nil {
|
||||
global.GVA_LOG.Warn("加载角色头像失败,使用默认头像",
|
||||
zap.String("avatar", character.Avatar),
|
||||
zap.Error(loadErr))
|
||||
img = createDefaultAvatar()
|
||||
}
|
||||
} else {
|
||||
img = createDefaultAvatar()
|
||||
}
|
||||
@@ -635,9 +643,14 @@ func (cs *CharacterService) ExportCharacterAsPNG(characterID uint, userID *uint)
|
||||
// 将角色卡数据嵌入到 PNG
|
||||
pngData, err := utils.EmbedCharacterToPNG(img, card)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("生成 PNG 失败", zap.Error(err))
|
||||
return nil, errors.New("生成 PNG 失败: " + err.Error())
|
||||
}
|
||||
|
||||
global.GVA_LOG.Info("PNG 导出成功",
|
||||
zap.Uint("characterID", characterID),
|
||||
zap.Int("size", len(pngData)))
|
||||
|
||||
return pngData, nil
|
||||
}
|
||||
|
||||
@@ -745,28 +758,49 @@ func convertCharacterToCard(character *app.AICharacter) *utils.CharacterCardV2 {
|
||||
}
|
||||
}
|
||||
|
||||
// loadAvatarImage 从文件系统或 URL 加载头像
|
||||
func loadAvatarImage(avatarPath string) (image.Image, error) {
|
||||
// 如果是 URL,暂时不支持
|
||||
if strings.HasPrefix(avatarPath, "http://") || strings.HasPrefix(avatarPath, "https://") {
|
||||
return nil, errors.New("暂不支持从 URL 加载头像")
|
||||
}
|
||||
|
||||
// 从文件系统加载
|
||||
file, err := os.Open(avatarPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("打开头像文件失败: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 解码图片(自动检测格式)
|
||||
img, _, err := image.Decode(file)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("解码头像图片失败: %w", err)
|
||||
}
|
||||
|
||||
return img, nil
|
||||
}
|
||||
|
||||
// createDefaultAvatar 创建默认头像
|
||||
func createDefaultAvatar() image.Image {
|
||||
// 创建一个 400x533 的默认图片(3:4 比例)
|
||||
width, height := 400, 533
|
||||
img := image.NewRGBA(image.Rect(0, 0, width, height))
|
||||
|
||||
// 填充渐变色
|
||||
// 填充渐变色(从紫色到蓝色)
|
||||
for y := 0; y < height; y++ {
|
||||
for x := 0; x < width; x++ {
|
||||
// 简单的渐变效果
|
||||
// 计算渐变颜色
|
||||
r := uint8(102 + y*155/height)
|
||||
g := uint8(126 + y*138/height)
|
||||
b := uint8(234 - y*72/height)
|
||||
img.Set(x, y, image.NewRGBA(image.Rect(0, 0, 1, 1)).At(0, 0))
|
||||
img.SetRGBA(x, y, image.NewRGBA(image.Rect(0, 0, 1, 1)).RGBAAt(0, 0))
|
||||
// 设置颜色
|
||||
img.SetRGBA(x, y, image.NewRGBA(image.Rect(0, 0, 1, 1)).RGBAAt(0, 0))
|
||||
|
||||
// 直接设置像素颜色
|
||||
pix := img.Pix[y*img.Stride+x*4:]
|
||||
pix[0] = r
|
||||
pix[1] = g
|
||||
pix[2] = b
|
||||
pix[3] = 255
|
||||
pix[3] = 255 // 完全不透明
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user