feat: 图片明暗分类改为子目录命名(图片_横屏_1080P/bright_20)
This commit is contained in:
@@ -9,7 +9,7 @@
|
|||||||
- **非标分辨率归类**:按像素区间(每 1024px 一档)自动归入 1K ~ 19K / 普通 / 原图(原画质)目录
|
- **非标分辨率归类**:按像素区间(每 1024px 一档)自动归入 1K ~ 19K / 普通 / 原图(原画质)目录
|
||||||
- **方向区分**:横屏、竖屏、等比(正方形)分开整理,GIF 单独处理
|
- **方向区分**:横屏、竖屏、等比(正方形)分开整理,GIF 单独处理
|
||||||
- **EXIF 旋转修正**:手机/相机竖拍的图(文件里横着存、带 EXIF 旋转标记)自动识别并转正——找到 ffmpeg 时用 ffmpeg 把像素真正转正;找不到时至少按"显示方向"(宽高对调)归类,不会再误入横屏目录
|
- **EXIF 旋转修正**:手机/相机竖拍的图(文件里横着存、带 EXIF 旋转标记)自动识别并转正——找到 ffmpeg 时用 ffmpeg 把像素真正转正;找不到时至少按"显示方向"(宽高对调)归类,不会再误入横屏目录
|
||||||
- **明暗分类**:基于 ITU-R BT.601 亮度公式分析每张图片明暗程度,暗色(亮度 < 80)像素占比为 darkScore、亮色(亮度 > 175)像素占比为 lightScore;以两者差幅判定亮暗主导,在目录名末尾追加 `-dark_N` / `-mid` / `-bright_N`(N 为占比四舍五入到 10% 的档位)
|
- **明暗分类**:基于 ITU-R BT.601 亮度公式分析每张图片明暗程度,暗色(亮度 < 80)像素占比为 darkScore、亮色(亮度 > 175)像素占比为 lightScore;以两者差幅判定亮暗主导,在分辨率目录下追加 `dark_N` / `mid` / `bright_N` 子目录(N 为占比四舍五入到 10% 的档位)
|
||||||
- **音频归类**:音频文件单独归入「音频」目录
|
- **音频归类**:音频文件单独归入「音频」目录
|
||||||
- **异常兜底**:读取失败、不支持的格式自动归入「读取异常」「已忽略」目录
|
- **异常兜底**:读取失败、不支持的格式自动归入「读取异常」「已忽略」目录
|
||||||
- **自动整理**:无需人工干预,扫描 → 分析 → 移动一次完成,跨磁盘自动降级为复制后删除
|
- **自动整理**:无需人工干预,扫描 → 分析 → 移动一次完成,跨磁盘自动降级为复制后删除
|
||||||
@@ -101,10 +101,10 @@ npm install && npm run dev
|
|||||||
### 图片
|
### 图片
|
||||||
|
|
||||||
```text
|
```text
|
||||||
{uid}-图片_横屏_720P-dark_100 ← 1280×720,暗色主导
|
{uid}-图片_横屏_720P/dark_100 ← 1280×720,暗色主导
|
||||||
{uid}-图片_横屏_1D5KP-mid ← 1600×900,明暗均衡
|
{uid}-图片_横屏_1D5KP/mid ← 1600×900,明暗均衡
|
||||||
{uid}-图片_横屏_1080P-bright_100 ← 1920×1080,亮色主导
|
{uid}-图片_横屏_1080P/bright_100 ← 1920×1080,亮色主导
|
||||||
{uid}-图片_横屏_2DKP-dark_70 ← 2048×1080(影院 2K)
|
{uid}-图片_横屏_2DKP/dark_70 ← 2048×1080(影院 2K)
|
||||||
{uid}-图片_竖屏_... ← 竖屏按同样规则(普通 / 1K~19K / 原图)
|
{uid}-图片_竖屏_... ← 竖屏按同样规则(普通 / 1K~19K / 原图)
|
||||||
{uid}-图片_等比_... ← 等比(正方形)按同样规则
|
{uid}-图片_等比_... ← 等比(正方形)按同样规则
|
||||||
{uid}-图片_GIF ← 所有 GIF 图片
|
{uid}-图片_GIF ← 所有 GIF 图片
|
||||||
@@ -145,7 +145,7 @@ darkScore = 亮度 < 80 的像素占比
|
|||||||
lightScore = 亮度 > 175 的像素占比
|
lightScore = 亮度 > 175 的像素占比
|
||||||
```
|
```
|
||||||
|
|
||||||
- **判定规则**:`lightScore` 高于 `darkScore` 15 个百分点以上归 `-bright_N`,反之归 `-dark_N`;差幅不足 15% 视为中性归 `-mid`(不强制二选一)
|
- **判定规则**:`lightScore` 高于 `darkScore` 15 个百分点以上归 `bright_N` 子目录,反之归 `dark_N` 子目录;差幅不足 15% 视为中性归 `mid`(不强制二选一),明暗名作为分辨率目录下的子目录(如 `图片_横屏_1080P/bright_20`)
|
||||||
- **档位命名**:N 为占比四舍五入到 10% 的档位(10~100),如 darkScore 0.70 → `dark_70`,表示占比命中 [N-5%, N+5%) 区间
|
- **档位命名**:N 为占比四舍五入到 10% 的档位(10~100),如 darkScore 0.70 → `dark_70`,表示占比命中 [N-5%, N+5%) 区间
|
||||||
- **透明处理**:完全透明的像素(alpha=0)不计入统计,全透明图片归 `-mid`
|
- **透明处理**:完全透明的像素(alpha=0)不计入统计,全透明图片归 `-mid`
|
||||||
- **性能**:大图(>100 万像素)先等比缩放为最长边 512px 的缩略图(纯内存)再统计明暗,内存占用与耗时大幅下降;超 4000 万像素的图片直接跳过明暗分析(按中性 mid 归类)避免 OOM
|
- **性能**:大图(>100 万像素)先等比缩放为最长边 512px 的缩略图(纯内存)再统计明暗,内存占用与耗时大幅下降;超 4000 万像素的图片直接跳过明暗分析(按中性 mid 归类)避免 OOM
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
// 大白话理解,就是定分类命名规则:
|
// 大白话理解,就是定分类命名规则:
|
||||||
// - 画面是横的还是竖的?(横屏 / 竖屏 / 正方形)
|
// - 画面是横的还是竖的?(横屏 / 竖屏 / 正方形)
|
||||||
// - 清晰度算哪个档?(720P / 1080P / 4K…;不标准的按长边大小给个约数,如 5K)
|
// - 清晰度算哪个档?(720P / 1080P / 4K…;不标准的按长边大小给个约数,如 5K)
|
||||||
// - 图片还要看是暗调还是亮调(dark / mid / light)
|
// - 图片还要看是暗调还是亮调(dark / mid / bright),作为子目录
|
||||||
//
|
//
|
||||||
// 最终拼出一个文件夹名,比如:
|
// 最终拼出一个文件夹名,比如:
|
||||||
// - 「图片_横屏_1080P-light」 一张横向、1080P、偏亮的图片
|
// - 「图片_横屏_1080P/bright_20」 一张横向、1080P、偏亮的图片
|
||||||
// - 「视频_竖屏_4k」 一个竖向、4K 的视频
|
// - 「视频_竖屏_4k」 一个竖向、4K 的视频
|
||||||
//
|
//
|
||||||
// 这个包全是"纯函数"——不依赖任何状态,给什么算什么,好理解也好测。
|
// 这个包全是"纯函数"——不依赖任何状态,给什么算什么,好理解也好测。
|
||||||
@@ -54,15 +54,15 @@ func (o Orientation) String() string {
|
|||||||
|
|
||||||
// ============================ 归类目录名 ============================
|
// ============================ 归类目录名 ============================
|
||||||
|
|
||||||
// ImageDir 返回一张图片该进的文件夹名,比如:
|
// ImageDir 返回一张图片该进的文件夹路径,比如:
|
||||||
// - 「图片_GIF」:GIF 动图单独放(不做明暗分类)
|
// - 「图片_GIF」:GIF 动图单独放(不做明暗分类)
|
||||||
// - 「图片_横屏_1080P-light」:普通图片 = 方向 + 清晰度 + 明暗
|
// - 「图片_横屏_1080P/bright_20」:普通图片 = 方向 + 清晰度,明暗作为其子目录
|
||||||
func ImageDir(ext string, width, height int, darkScore, lightScore float64) string {
|
func ImageDir(ext string, width, height int, darkScore, lightScore float64) string {
|
||||||
if strings.EqualFold(ext, ".gif") {
|
if strings.EqualFold(ext, ".gif") {
|
||||||
return "图片_GIF"
|
return "图片_GIF"
|
||||||
}
|
}
|
||||||
dir := resolutionDir("图片", ext, width, height)
|
dir := resolutionDir("图片", ext, width, height)
|
||||||
return dir + "-" + BrightnessName(darkScore, lightScore)
|
return dir + "/" + BrightnessName(darkScore, lightScore)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VideoDir 返回一个视频该进的文件夹名,比如「视频_竖屏_4k」「视频_横屏_GIF」。
|
// VideoDir 返回一个视频该进的文件夹名,比如「视频_竖屏_4k」「视频_横屏_GIF」。
|
||||||
|
|||||||
Reference in New Issue
Block a user