- 重构后端与前端,全程大白话注释(不懂程序也能看懂) - 移动阶段改为全局并行(MoveAll,工人数=CPU核心数) - 去掉记录每个文件搬去哪了(删除去向回填,解决写库卡顿) - 去掉重复文件标记与统计:重复判定改为 MD5+路径都相同才算,重复则原地忽略不移动;MD5 相同但路径不同仍照常搬 - 媒体库去掉归类目录列,看板去掉重复/归类分布统计
62 lines
2.1 KiB
Go
62 lines
2.1 KiB
Go
package classify
|
||
|
||
import "fmt"
|
||
|
||
// standardResolution 一条"标准分辨率"规则:宽高精确对上就算这个档位。
|
||
// 比如 1920×1080 就叫"1080P",而不是按长边算成"1K"。
|
||
type standardResolution struct {
|
||
width int
|
||
height int
|
||
suffix string // 这个档位叫什么名(也用作文件夹名 / 筛选标签)
|
||
}
|
||
|
||
// 标准分辨率表:都是一些大家熟悉的清晰度档位。
|
||
// (1D5KP、2DKP、2D5KP 这些是介于常见档位之间的中间值,能对上就精确分类,对不上就按约数。)
|
||
var standardResolutions = []standardResolution{
|
||
{1280, 720, "720P"}, // 720p 标准高清
|
||
{1600, 900, "1D5KP"}, // 介于 720P 与 1080P 之间
|
||
{1920, 1080, "1080P"}, // 1080p 全高清
|
||
{2048, 1080, "2DKP"}, // 影院 2K
|
||
{2560, 1440, "2D5KP"}, // 2.5K
|
||
{2560, 1080, "UltraWide2KP"}, // 带鱼屏
|
||
{3440, 1440, "UltraWide3KP"}, // 带鱼屏
|
||
{5120, 2160, "UltraWide4KP"}, // 带鱼屏
|
||
{3840, 2160, "4KP"}, // 主流 4K
|
||
{4096, 2160, "4KHP"}, // DCI 影院 4K
|
||
{7680, 4320, "8KP"}, // 8K
|
||
}
|
||
|
||
// 非标准分辨率的"约数"分档参数:
|
||
// - 长边不足 1024px 的,叫「普通」;
|
||
// - 每满 1024px 一档,叫 1K、2K … 19K;
|
||
// - 超过 19K 的,叫「原图」(视频叫「原画质」)。
|
||
const (
|
||
bucketStep = 1024 // 每 1024 像素算一档
|
||
maxLevel = 19 // 最高算到 19K
|
||
)
|
||
|
||
// matchStandard 精确匹配标准分辨率:宽高都对上就返回档位名,否则返回空串。
|
||
func matchStandard(width, height int) string {
|
||
for _, r := range standardResolutions {
|
||
if r.width == width && r.height == height {
|
||
return r.suffix
|
||
}
|
||
}
|
||
return ""
|
||
}
|
||
|
||
// levelName 按长边分档:
|
||
// - 不到一档(<1024px):「普通」
|
||
// - 1K~19K:按 1024px 一档,几档就叫几 K
|
||
// - 超过 19K:用调用方给的兜底名(图片「原图」/ 视频「原画质」)
|
||
func levelName(longEdge int, overflow string) string {
|
||
if longEdge < bucketStep {
|
||
return "普通"
|
||
}
|
||
level := longEdge / bucketStep
|
||
if level > maxLevel {
|
||
return overflow
|
||
}
|
||
return fmt.Sprintf("%dK", level)
|
||
}
|