Craiyon 生成结果本地归档与重命名的批处理脚本

文章导读
Craiyon 下载目录里的图片名通常是一串随机字符,手工改名为“日期+批次+关键词”很耗时间。解决思路是:不碰 Craiyon 接口,只用 Python 扫描本地目录,按扩展名和修改时间筛选图片,再按自定义模板重命名并移动到按年/月/项目组织的目录。脚本只做文件系统操作,结果是否可靠可以直接用文件树核对。
📋 目录
  1. A 识别Craiyon下载目录的文件特征
  2. B 设计基于内容的命名模板
  3. C 实现自动创建目标文件夹结构
  4. D 编写重命名与移动的核心代码
  5. E 验证脚本处理后的文件树
A A

Craiyon 下载目录里的图片名通常是一串随机字符,手工改名为“日期+批次+关键词”很耗时间。解决思路是:不碰 Craiyon 接口,只用 Python 扫描本地目录,按扩展名和修改时间筛选图片,再按自定义模板重命名并移动到按年/月/项目组织的目录。脚本只做文件系统操作,结果是否可靠可以直接用文件树核对。

适用:需要把 Craiyon 批量下载的 PNG/JPG 等图片按日期和关键词归档。动作:用 glob 按扩展名筛图,用 os.path.getmtime 限定处理范围,再用 shutil.move 把图片移到 YYYY/MM 目录并重命名。验证:运行后对比源目录剩余文件和目标目录树。边界:不识别图片内容,不调用 Craiyon API;同目录不得有两批不同项目的未归档图片,否则会混淆关键词。

识别Craiyon下载目录的文件特征

Craiyon 输出目录通常同时存在 PNG、WebP、JPG 和可能的文本说明文件。归档前先用扩展名把图片挑出来,再用修改时间限定本次要处理的文件。这样可以避免把旧文件、非图片文件一起移动。

import glob
import os
import time

src_dir = r'D:/Downloads/Craiyon'
image_exts = {'.png', '.jpg', '.jpeg', '.webp', '.gif'}
cutoff = time.time() - 24 * 3600  # 只处理最近 24 小时内修改的文件

candidates = []
for ext in image_exts:
    for path in glob.glob(os.path.join(src_dir, '*' + ext)):
        if os.path.isfile(path) and os.path.getmtime(path) >= cutoff:
            candidates.append(path)

print('待处理图片数:', len(candidates))

设计基于内容的命名模板

命名模板建议包含日期、枚举序号和用户输入的关键词。日期从文件的修改时间提取,序号用于区分同一秒内生成的多个图片,关键词在脚本运行时输入。生成的文件名形如 20250315_1430_cat_001.png,可以直接按时间排序。关键词建议只用字母、数字和下划线,避免 Windows 文件名非法字符。

import datetime

def build_new_name(old_path, keyword, seq, ext):
    ts = datetime.datetime.fromtimestamp(os.path.getmtime(old_path))
    return f'{ts:%Y%m%d_%H%M}_{keyword}_{seq:03d}{ext.lower()}'

实现自动创建目标文件夹结构

目标目录建议按“项目/年/月”创建,同一项目下的图片按月归档,关键词不同也互不干扰。用 os.makedirs(... exist_ok=True) 可以把建目录和容错一起完成。

Craiyon 生成结果本地归档与重命名的批处理脚本
import os
import datetime

def get_target_dir(root, project, old_path):
    ts = datetime.datetime.fromtimestamp(os.path.getmtime(old_path))
    year = ts.strftime('%Y')
    month = ts.strftime('%m')
    target_dir = os.path.join(root, project, year, month)
    os.makedirs(target_dir, exist_ok=True)
    return target_dir

编写重命名与移动的核心代码

核心函数先根据文件修改时间生成新名字,再检查目标路径是否存在;存在时自动递增序号,最后用 shutil.move 完成移动。这样不会覆盖已有文件。

import shutil

def archive_file(old_path, target_root, project, keyword):
    ext = os.path.splitext(old_path)[1].lower()
    seq = 1
    while True:
        new_name = build_new_name(old_path, keyword, seq, ext)
        target_dir = get_target_dir(target_root, project, old_path)
        dest = os.path.join(target_dir, new_name)
        if not os.path.exists(dest):
            break
        seq += 1
    shutil.move(old_path, dest)
    return dest

project = input('输入归档项目名:').strip()
keyword = input('输入本次关键词:').strip()
for path in candidates:
    archive_file(path, r'D:/CraiyonArchive', project, keyword)

验证脚本处理后的文件树

归档后要检查两个位置:源目录里是否只剩不匹配本次条件的文件,目标目录里是否出现预期的项目/年/月层级。可以先用 tree 看结构,再用 os.walk 列出所有文件核对。

# Windows
tree /F D:/CraiyonArchive

# Linux / macOS
tree /path/to/CraiyonArchive
import os

for root, dirs, files in os.walk(r'D:/CraiyonArchive'):
    for name in files:
        print(os.path.join(root, name))

对照第一小节输出的 candidates 数量和这里列出的文件数量,并抽查几个文件名是否符合 日期_关键词_序号 规则。若源目录里还有图片,先确认它是否满足扩展名和修改时间条件,再决定是否扩大筛选范围。如果系统没有 tree 命令,直接用 os.walk 示例即可完成核对。