91 lines
1.9 KiB
Go
91 lines
1.9 KiB
Go
package sprite
|
||
|
||
import (
|
||
"bytes"
|
||
"image"
|
||
"image/gif"
|
||
_ "image/jpeg" // 注册JPEG解码器
|
||
_ "image/png" // 注册PNG解码器
|
||
"io"
|
||
"os"
|
||
)
|
||
|
||
// LoadImageFile 从文件加载图像,支持PNG、JPEG、GIF和静态WebP格式
|
||
func LoadImageFile(filePath string) ([]image.Image, error) {
|
||
// 读取文件内容
|
||
fileData, err := os.ReadFile(filePath)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return LoadImageData(fileData)
|
||
}
|
||
|
||
// LoadImageData 从字节数据加载图像,支持PNG、JPEG、GIF和静态WebP格式
|
||
func LoadImageData(fileData []byte) ([]image.Image, error) {
|
||
// 创建Reader
|
||
reader := bytes.NewReader(fileData)
|
||
|
||
// 尝试解码为GIF
|
||
if isGIF(fileData) {
|
||
return decodeGIF(reader)
|
||
}
|
||
|
||
// 尝试使用通用图像解码器(处理PNG、JPEG等)
|
||
img, _, err := image.Decode(bytes.NewReader(fileData))
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// 返回单帧图像
|
||
return []image.Image{img}, nil
|
||
}
|
||
|
||
// isGIF 检查数据是否为GIF格式
|
||
func isGIF(data []byte) bool {
|
||
return len(data) > 3 && data[0] == 'G' && data[1] == 'I' && data[2] == 'F'
|
||
}
|
||
|
||
// decodeGIF 解码GIF文件为图像帧序列
|
||
func decodeGIF(reader io.Reader) ([]image.Image, error) {
|
||
// 解码GIF
|
||
gifImg, err := gif.DecodeAll(reader)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// 检查帧数量
|
||
frameCount := len(gifImg.Image)
|
||
if frameCount == 0 {
|
||
return nil, nil
|
||
}
|
||
|
||
// 提取所有帧
|
||
images := make([]image.Image, frameCount)
|
||
for i, frame := range gifImg.Image {
|
||
images[i] = frame
|
||
}
|
||
|
||
return images, nil
|
||
}
|
||
|
||
// LoadSpriteFromFile 从文件创建一个精灵
|
||
func LoadSpriteFromFile(name string, filePath string) (*Sprite, error) {
|
||
// 加载图像
|
||
images, err := LoadImageFile(filePath)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// 创建精灵
|
||
sprite := &Sprite{
|
||
Name: name,
|
||
Images: images,
|
||
CurrentFrame: 0,
|
||
Position: image.Point{X: 0, Y: 0},
|
||
Index: 0,
|
||
}
|
||
|
||
return sprite, nil
|
||
}
|