Files
backend/internal/service/skin_renderer/minecraft.go

114 lines
3.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package skin_renderer
import (
"image"
"image/color"
"image/draw"
)
// Minecraft 提供 Minecraft 皮肤渲染的入口方法
// 与 blessing/texture-renderer 的 Minecraft 类保持兼容
type Minecraft struct{}
// NewMinecraft 创建 Minecraft 渲染器实例
func NewMinecraft() *Minecraft {
return &Minecraft{}
}
// RenderSkin 渲染完整皮肤预览(正面+背面)
// ratio: 缩放比例,默认 7.0
// isAlex: 是否为 Alex 模型(细手臂)
func (m *Minecraft) RenderSkin(skinData []byte, ratio float64, isAlex bool) (image.Image, error) {
vp := 15 // vertical padding
hp := 30 // horizontal padding
ip := 15 // internal padding
// 渲染正面(-45度
frontRenderer := NewSkinRenderer(ratio, false, -45, -25)
front, err := frontRenderer.Render(skinData, isAlex)
if err != nil {
return nil, err
}
// 渲染背面135度
backRenderer := NewSkinRenderer(ratio, false, 135, -25)
back, err := backRenderer.Render(skinData, isAlex)
if err != nil {
return nil, err
}
width := front.Bounds().Dx()
height := front.Bounds().Dy()
// 创建画布
canvas := createEmptyCanvas((hp+width+ip)*2, vp*2+height)
// 绘制背面(左侧)
draw.Draw(canvas, image.Rect(hp, vp, hp+width, vp+height), back, back.Bounds().Min, draw.Over)
// 绘制正面(右侧)
draw.Draw(canvas, image.Rect(hp+width+ip*2, vp, hp+width*2+ip*2, vp+height), front, front.Bounds().Min, draw.Over)
return canvas, nil
}
// RenderCape 渲染披风
// height: 输出高度
func (m *Minecraft) RenderCape(capeData []byte, height int) (image.Image, error) {
vp := 20 // vertical padding
hp := 40 // horizontal padding
renderer := NewCapeRenderer()
cape, err := renderer.Render(capeData, height)
if err != nil {
return nil, err
}
width := cape.Bounds().Dx()
capeHeight := cape.Bounds().Dy()
canvas := createEmptyCanvas(hp*2+width, vp*2+capeHeight)
draw.Draw(canvas, image.Rect(hp, vp, hp+width, vp+capeHeight), cape, cape.Bounds().Min, draw.Over)
return canvas, nil
}
// Render2DAvatar 渲染 2D 头像
// ratio: 缩放比例,默认 15.0
func (m *Minecraft) Render2DAvatar(skinData []byte, ratio float64) (image.Image, error) {
renderer := NewSkinRendererFull(ratio, true, 0, 0, 0, 0, 0, 0, 0, true)
return renderer.Render(skinData, false)
}
// Render3DAvatar 渲染 3D 头像
// ratio: 缩放比例,默认 15.0
func (m *Minecraft) Render3DAvatar(skinData []byte, ratio float64) (image.Image, error) {
renderer := NewSkinRenderer(ratio, true, 45, -25)
return renderer.Render(skinData, false)
}
// RenderSkinWithAngle 渲染指定角度的皮肤
func (m *Minecraft) RenderSkinWithAngle(skinData []byte, ratio float64, isAlex bool, hRotation, vRotation float64) (image.Image, error) {
renderer := NewSkinRenderer(ratio, false, hRotation, vRotation)
return renderer.Render(skinData, isAlex)
}
// RenderHeadWithAngle 渲染指定角度的头像
func (m *Minecraft) RenderHeadWithAngle(skinData []byte, ratio float64, hRotation, vRotation float64) (image.Image, error) {
renderer := NewSkinRenderer(ratio, true, hRotation, vRotation)
return renderer.Render(skinData, false)
}
// createEmptyCanvas 创建透明画布
func createEmptyCanvas(width, height int) *image.RGBA {
img := image.NewRGBA(image.Rect(0, 0, width, height))
// 填充透明背景
transparent := color.RGBA{0, 0, 0, 0}
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
img.SetRGBA(x, y, transparent)
}
}
return img
}