暂存服务端渲染功能,材质渲染计划迁移至前端
This commit is contained in:
113
internal/service/skin_renderer/minecraft.go
Normal file
113
internal/service/skin_renderer/minecraft.go
Normal file
@@ -0,0 +1,113 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user