topfans/backend/services/laserCompositor/uploader/oss_uploader.go
2026-06-03 22:19:22 +08:00

101 lines
2.5 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 uploader
import (
"bytes"
"fmt"
"image/png"
"math/rand"
"strings"
"time"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"github.com/topfans/laserCompositor/config"
)
// OSSUploader OSS 上传器
type OSSUploader struct {
cfg config.OSSConfig
}
// NewOSSUploader 创建 OSS 上传器
func NewOSSUploader(cfg config.OSSConfig) *OSSUploader {
return &OSSUploader{cfg: cfg}
}
// UploadResult 上传结果
type UploadResult struct {
OSSKey string `json:"oss_key"`
SignedURL string `json:"signed_url"`
}
// UploadPNG 上传 PNG 到 OSS返回 oss_key 和 signed_url
func (u *OSSUploader) UploadPNG(data []byte, dir, filename string) (*UploadResult, error) {
bucket, err := u.getBucket()
if err != nil {
return nil, err
}
if dir == "" {
dir = "laser-card/"
}
if filename == "" {
filename = fmt.Sprintf("%d_%d.png", time.Now().UnixMilli(), rand.Intn(10000))
}
ossKey := strings.TrimRight(dir, "/") + "/" + filename
err = bucket.PutObject(ossKey, bytes.NewReader(data))
if err != nil {
return nil, fmt.Errorf("OSS upload failed: %w", err)
}
// 生成签名 URL1 小时有效)
signedURL, err := bucket.SignURL(ossKey, oss.HTTPGet, 3600)
if err != nil {
return nil, fmt.Errorf("sign URL failed: %w", err)
}
return &UploadResult{
OSSKey: ossKey,
SignedURL: signedURL,
}, nil
}
// UploadPNG 变体:上传并返回带签名的 URL
func (u *OSSUploader) getBucket() (*oss.Bucket, error) {
ak := strings.TrimSpace(u.cfg.AccessKeyID)
sk := strings.TrimSpace(u.cfg.AccessKeySecret)
if ak == "" || sk == "" {
return nil, fmt.Errorf("OSS credentials not configured")
}
endpoint := fmt.Sprintf("https://oss-%s.aliyuncs.com", u.cfg.Region)
client, err := oss.New(endpoint, ak, sk)
if err != nil {
return nil, fmt.Errorf("create OSS client: %w", err)
}
bucket, err := client.Bucket(u.cfg.BucketName)
if err != nil {
return nil, fmt.Errorf("get bucket: %w", err)
}
return bucket, nil
}
// EncodePNG 将 compositor.ComposeResult 编码为 PNG bytes
func EncodePNG(width, height int, data []byte) ([]byte, error) {
// 如果 data 已经是完整的 PNG 数据,直接返回
if len(data) > 4 && data[0] == 0x89 && data[1] == 0x50 && data[2] == 0x4e && data[3] == 0x47 {
return data, nil
}
var buf bytes.Buffer
// 这里 data 预期是 raw RGBA pixels
// 但实际上 compositor 返回的是 NRGBA image
// 暂时返回空,由调用方在 handler 层处理
if err := png.Encode(&buf, nil); err != nil {
return nil, err
}
return buf.Bytes(), nil
}