webp fix v1
This commit is contained in:
+36
-9
@@ -712,16 +712,41 @@ func uploadImage(ctx context.Context, opts uploadImageOptions) error {
|
||||
now := time.Now()
|
||||
switch format {
|
||||
case "gif":
|
||||
// GIF 保持原样上传,不转换(动画 GIF 需要 cwebp 工具支持)
|
||||
uploadData = originalData
|
||||
contentType = "image/gif"
|
||||
uploadKey = fmt.Sprintf("%d/%d/%d%s", now.Year(), now.Month(), now.UnixNano(), fileExt)
|
||||
// 与 storage.UploadPictureToS3 走同一实现,避免同一张 GIF 在两个入口
|
||||
// 得到不同格式/体积(此前此处完全跳过转换)。
|
||||
webpData, err := storage.ConvertGifToAnimatedWebP(originalData)
|
||||
if err != nil || len(webpData) >= len(originalData) {
|
||||
if err != nil {
|
||||
logrus.WithError(err).Warn("animated WebP conversion failed, falling back to original GIF")
|
||||
}
|
||||
uploadData = originalData
|
||||
contentType = "image/gif"
|
||||
uploadKey = fmt.Sprintf("%d/%d/%d%s", now.Year(), now.Month(), now.UnixNano(), fileExt)
|
||||
} else {
|
||||
uploadData = webpData
|
||||
contentType = "image/webp"
|
||||
uploadKey = fmt.Sprintf("%d/%d/%d%s", now.Year(), now.Month(), now.UnixNano(), ".webp")
|
||||
}
|
||||
default:
|
||||
// JPEG / PNG 等静态图片转换为 WebP
|
||||
webpData, err := storage.ConvertStaticImageToWebP(bytes.NewReader(originalData))
|
||||
if err != nil {
|
||||
// 转换失败时回退为原始数据
|
||||
logrus.WithError(err).Warn("WebP conversion failed, falling back to original format")
|
||||
// JPEG / PNG 等静态图片转换为 WebP。这里只取 DecodeConfig(不波纹解像素),
|
||||
// 避免在像素量已经 CheckPixelLimit 校验过的超大图上再解码一遍。
|
||||
cfg, _, cfgErr := image.DecodeConfig(bytes.NewReader(originalData))
|
||||
// 已是 WebP 且尺寸合规 -> 原样上传:再编码会白丢一代有损画质。
|
||||
if format == "webp" && cfgErr == nil &&
|
||||
cfg.Width <= storage.GeneralEncodeSpec.MaxSide && cfg.Height <= storage.GeneralEncodeSpec.MaxSide {
|
||||
uploadData = originalData
|
||||
contentType = "image/webp"
|
||||
uploadKey = fmt.Sprintf("%d/%d/%d%s", now.Year(), now.Month(), now.UnixNano(), fileExt)
|
||||
break
|
||||
}
|
||||
|
||||
webpData, err := storage.ConvertStaticImageToWebP(bytes.NewReader(originalData), storage.GeneralEncodeSpec)
|
||||
if err != nil || len(webpData) >= len(originalData) {
|
||||
// 转换失败,或转换后并不比原图小(小图标/线框图/已优化 JPEG 上有损 WebP
|
||||
// 可能反而更大)—— 一律沿用原图。
|
||||
if err != nil {
|
||||
logrus.WithError(err).Warn("WebP conversion failed, falling back to original format")
|
||||
}
|
||||
uploadData = originalData
|
||||
contentType = contentTypeFromFormat(format)
|
||||
uploadKey = fmt.Sprintf("%d/%d/%d%s", now.Year(), now.Month(), now.UnixNano(), fileExt)
|
||||
@@ -743,6 +768,8 @@ func uploadImage(ctx context.Context, opts uploadImageOptions) error {
|
||||
Body: bytes.NewReader(uploadData),
|
||||
ContentLength: aws.Int64(int64(len(uploadData))),
|
||||
ContentType: aws.String(contentType),
|
||||
// key 含纳秒时间戳且内容不可变,与 storage.uploadPictureToS3 保持一致的 immutable 强缓存。
|
||||
CacheControl: aws.String("public, max-age=31536000, immutable"),
|
||||
}); err != nil {
|
||||
return errors.Wrap(err, "put object")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user