优化缩略图
This commit is contained in:
1 parent
e94dfb9e35
commit
081520dbd9
5 files changed
+259
-15
No files matched your search
+33
-4
@@ -3,13 +3,14 @@
|
||||
/**
|
||||
* 动态缩略图的档位配置。
|
||||
*
|
||||
* 每项是 [细节分辨率, 帧率, 编码质量]:
|
||||
* 每项是 [细节分辨率, 帧率, 编码质量],作为搜索路径上的锚点:
|
||||
* - 细节分辨率决定画面保留多少细节(输出画布始终 400×400,小分辨率会被放大填满);
|
||||
* - 帧率决定每秒采样多少帧,只改采样密度不改时间轴,每档的帧延迟会自动重算;
|
||||
* - 编码质量是 0–1 的 WebP 质量,APNG 是无损编码会忽略这一项。
|
||||
* 数组顺序就是生成顺序,也是画廊里的展示顺序。
|
||||
*
|
||||
* 想调整压缩策略,直接改下面的数字即可;增删档位也支持,每档自带质量。
|
||||
* 数组顺序是从最高画质到最低画质的搜索方向。运行时会在相邻锚点之间插值成一条更密的
|
||||
* 路径,再按用户填写的目标体积在路径上二分定位,取命中位置附近若干档完整生成,
|
||||
* 所以锚点的疏密决定可搜索的粒度,锚点数量决定画廊里的候选数量。
|
||||
*/
|
||||
const ANIMATED_PRIORITIES = {
|
||||
// 分辨率优先:先把帧率压到底,再降分辨率。
|
||||
@@ -31,9 +32,37 @@ const ANIMATED_PRIORITIES = {
|
||||
|
||||
const DEFAULT_PRIORITY = 'resolution';
|
||||
|
||||
// 相邻锚点之间插多少个采样点。数值越大,越容易压在目标体积附近,但粗估阶段耗时略增。
|
||||
const PATH_STEPS_PER_SEGMENT = 6;
|
||||
|
||||
function animatedProfiles(priority) {
|
||||
const plan = ANIMATED_PRIORITIES[priority] || ANIMATED_PRIORITIES[DEFAULT_PRIORITY];
|
||||
return plan.map(([size, fps, quality]) => ({ size, fps, quality }));
|
||||
}
|
||||
|
||||
module.exports = { ANIMATED_PRIORITIES, DEFAULT_PRIORITY, animatedProfiles };
|
||||
/**
|
||||
* 把锚点路径插值成更密的采样路径,供按目标体积二分定位使用。
|
||||
* 分辨率取整、帧率至少 1、质量保留两位小数;首尾锚点原样保留。
|
||||
*/
|
||||
function expandAnimatedPath(priority) {
|
||||
const anchors = ANIMATED_PRIORITIES[priority] || ANIMATED_PRIORITIES[DEFAULT_PRIORITY];
|
||||
const lerp = (from, to, t) => from + (to - from) * t;
|
||||
const path = [];
|
||||
for (let index = 0; index < anchors.length - 1; index++) {
|
||||
const [fromSize, fromFps, fromQuality] = anchors[index];
|
||||
const [toSize, toFps, toQuality] = anchors[index + 1];
|
||||
for (let step = 0; step < PATH_STEPS_PER_SEGMENT; step++) {
|
||||
const t = step / PATH_STEPS_PER_SEGMENT;
|
||||
path.push({
|
||||
size: Math.round(lerp(fromSize, toSize, t)),
|
||||
fps: Math.max(1, Math.round(lerp(fromFps, toFps, t))),
|
||||
quality: Math.round(lerp(fromQuality, toQuality, t) * 100) / 100,
|
||||
});
|
||||
}
|
||||
}
|
||||
const [size, fps, quality] = anchors[anchors.length - 1];
|
||||
path.push({ size, fps, quality });
|
||||
return path;
|
||||
}
|
||||
|
||||
module.exports = { ANIMATED_PRIORITIES, DEFAULT_PRIORITY, PATH_STEPS_PER_SEGMENT, animatedProfiles, expandAnimatedPath };
|
||||
Reference in new issue
Block a user