diff --git a/server/src/WebDrop.Core/AvatarData.cs b/server/src/WebDrop.Core/AvatarData.cs
index d65d137..143d99c 100644
--- a/server/src/WebDrop.Core/AvatarData.cs
+++ b/server/src/WebDrop.Core/AvatarData.cs
@@ -12,7 +12,7 @@ public static class AvatarData
/// 缩略图(列表、聊天里默认分发的有损小图)的上限:静态约 75 KB,动图约 370 KB
public const int MaxThumbStaticChars = 100_000;
- public const int MaxThumbGifChars = 500_000;
+ public const int MaxThumbGifChars = 800_000;
private static readonly string[] Prefixes = ["data:image/png;base64,", "data:image/jpeg;base64,", "data:image/webp;base64,", "data:image/gif;base64,"];
diff --git a/web/src/features/home/avatarGif.ts b/web/src/features/home/avatarGif.ts
index 230208d..dc5a560 100644
--- a/web/src/features/home/avatarGif.ts
+++ b/web/src/features/home/avatarGif.ts
@@ -87,12 +87,15 @@ export async function exportGifAvatar(frames: readonly GifFrame[], crop: Crop, f
throw new Error('动图压缩后仍然过大,请换一张更短或更小的 GIF');
}
-/** 动图的有损缩略图:帧数、颜色数和尺寸都压小(最多约 30 帧,64 色,80 像素),控制在 40 万字符以内。列表、聊天里默认用它 */
+/**
+ * 动图的有损缩略图:尺寸和颜色压小,帧数尽量保持和原图一样(隔帧是最后的手段,会丢掉流畅度)。
+ * 控制在服务端上限(80 万字符)以内。列表、聊天里默认用它
+ */
export async function exportGifThumb(frames: readonly GifFrame[], crop: Crop, from: number): Promise {
- for (const [size, maxFrames, colors] of [[80, 30, 64], [64, 24, 32], [48, 16, 32]] as const) {
+ for (const [size, step, colors] of [[80, 1, 64], [64, 1, 48], [64, 1, 32], [48, 1, 32], [64, 2, 32], [48, 2, 32], [40, 3, 16]] as const) {
await new Promise((resolve) => setTimeout(resolve, 0));
- const url = encode(frames, crop, from, size, Math.max(1, Math.ceil(frames.length / maxFrames)), colors);
- if (url.length <= 400_000) return url;
+ const url = encode(frames, crop, from, size, step, colors);
+ if (url.length <= 780_000) return url;
}
throw new Error('动图缩略图生成失败');
}