Fork me on GitHub

我做了一个 AI 图片重命名工具:看懂照片内容,再生成有意义的文件名

整理旅行照片时,我经常遇到一个问题:相机和手机生成的文件名通常是 IMG_8428.JPG IMG_0698.JPG 这样的编号。

当照片数量较少时,还可以逐张打开查看;但一次旅行拍摄几十甚至几百张照片后,仅凭文件名几乎无法知道照片内容。想找到“国清寺古建筑”“天台山瀑布合影”或者“琼台仙谷悬索桥”,只能不断翻看缩略图。

为了解决这个问题,我开发了一个带图形界面的 Python 工具:AI 照片与视频重命名器。

它可以调用本地视觉模型识别照片内容,自动生成类似下面这样的文件名:

IMG_0506.JPG
→ 20260812-天台山大瀑布景区-一家三口合影.JPG

IMG_8428.JPG
→ 20260813-国清寺-黄墙古树与石狮.JPG

IMG_8422.JPG
→ 20260812-琼台仙谷-悬索桥近景.JPG

相比没有含义的相机编号,这样的名称更容易搜索、归档和长期保存。

视频演示

这个工具能做什么?

工具使用 Python 和 Tkinter 开发,提供了一个轻量的桌面操作界面。用户不需要编写命令,只需要选择媒体目录、配置模型,然后按照“扫描—分析—预览—确认”的流程操作。

目前支持以下功能:

  • 选择指定的图片或视频目录
  • 可选择是否递归扫描子目录
  • 支持 JPG、JPEG、PNG、WebP 和 BMP 图片
  • 支持 MOV、MP4、M4V、AVI 和 MKV 视频
  • 在界面或 .env 中配置接口类型、模型、API 地址和可选 API Key
  • 支持 Ollama 原生接口:/api/chat 和 /api/tags
  • 支持 OpenAI 兼容接口:/v1/chat/completions 和 /v1/models
  • 自动生成带日期和场景描述的文件名
  • 重命名前预览全部结果
  • 支持手工修改 AI 生成的名称
  • 自动清理 Windows 文件名中的非法字符
  • 自动处理同名文件并添加序号
  • 不覆盖目录中已经存在的文件
  • 批量重命名失败时尝试回滚

整个过程只会修改文件名,不会修改图片、视频内容或照片中的 EXIF 信息。

为什么支持本地视觉模型?

这款工具默认可以连接本机运行的 Ollama 服务。当前也支持通过 LLM_API_TYPE 切换到 OpenAI 兼容接口:

# Ollama 原生接口
LLM_API_TYPE=ollama
LLM_MODEL=qwen3.8:27b
LLM_API_HOST=http://127.0.0.1:11434
LLM_API_KEY=

如果使用 OpenAI 兼容服务,可以这样配置:

LLM_API_TYPE=openai
LLM_MODEL=你的视觉模型
LLM_API_HOST=https://你的服务地址/v1
LLM_API_KEY=你的密钥

LLM_API_TYPE 只有两个取值:ollama 和 openai,默认是 ollama。OpenAI 模式会请求标准的 /v1/chat/completions 接口,并将压缩后的图片作为视觉输入发送;如果地址已经以 /v1 结尾,程序不会重复追加路径。

1. 本地模型可以减少隐私顾虑

当 API 地址配置为 127.0.0.1 或其他本机回环地址时,图片分析请求只发送给本机运行的模型服务。家庭照片、旅行合影等内容不需要上传到外部云平台。

如果配置的是远程 Ollama 或 OpenAI 兼容服务,图片仍然会发送到该服务。因此,使用前应确认服务的隐私政策、数据处理方式和访问控制;远程 HTTP 地址也应改用 HTTPS。

2. 模型可以自由切换

模型名称、接口类型和 API 地址都可以在 .env 文件或图形界面中配置。OpenAI 兼容服务如果需要鉴权,可以填写 LLM_API_KEY,本地不需要鉴权的服务则可以留空。

需要注意的是,所选模型必须支持视觉输入。纯文本模型无法识别照片内容。

图片和视频是怎样处理的?

直接把数 MB 甚至十几 MB 的原图发送给模型,会占用较多内存和视觉 Token。为此,程序会先对图片进行预处理:

  1. 读取并修正照片的 EXIF 方向;
  2. 将图片最长边缩小到 1280 像素;
  3. 转换为适合模型分析的 JPEG 数据;
  4. 根据接口类型生成请求:Ollama 使用 images 字段,OpenAI 兼容接口使用 data:image/jpeg;base64,... 的 image_url;
  5. 解析模型返回的文件名描述,并清理 Windows 不允许的字符。

这个过程只在内存中生成缩略图,不会修改原始照片。

对于视频,程序会通过 FFmpeg 获取视频时长,抽取中间位置的一帧,然后让视觉模型根据这一帧生成名称。临时画面会在分析结束后自动删除。

这种方案无法概括长视频的全部内容,但对于手机拍摄的短视频、Live Photo 片段和旅行记录,通常已经能够提供有意义的名称。

为什么不让 AI 直接修改文件?

AI 生成的名称并不一定每次都完全准确。例如,它可能无法确定具体景点,或者把人物关系描述得过于笼统。

因此,这个工具没有采用“分析后立即重命名”的方式,而是加入了一个预览确认流程:

  1. 扫描目录中的媒体文件;
  2. AI 逐个分析并生成建议名称;
  3. 用户检查全部结果;
  4. 对不满意的名称进行手工修改;
  5. 最后统一确认并应用。

只有用户点击“应用重命名”并再次确认后,程序才会真正修改文件名。

文件安全方面做了哪些处理?

批量重命名看起来简单,但需要考虑文件重名、非法字符和中途失败等情况。

程序会自动清理 Windows 不允许出现在文件名中的字符:

< > : " / \ | ? *

如果多个文件得到相同的名称,程序会自动添加序号:

天台山大瀑布-瀑布近景.JPG
天台山大瀑布-瀑布近景-02.JPG
天台山大瀑布-瀑布近景-03.JPG

正式重命名前,程序还会检查目标文件是否已经存在,避免覆盖原有文件。

批量操作采用两阶段重命名:文件首先被改成唯一的临时名称,确认全部进入临时状态后,再转换成最终名称。如果过程中发生异常,程序会尽可能恢复原始文件名。

安装和运行

项目使用独立的 Python 虚拟环境,不会把依赖安装到系统 Python 中。

进入项目目录后运行:

powershell -ExecutionPolicy Bypass -File .\setup.ps1

安装脚本会自动:

  • 创建 .venv;
  • 安装锁定版本的 Python 依赖;
  • 在缺少 .env 时从模板创建配置文件。

然后编辑 .env。继续使用 Ollama 时:

LLM_API_TYPE=ollama
LLM_MODEL=qwen3.8:27b
LLM_API_HOST=http://127.0.0.1:11434
LLM_API_KEY=

切换到 OpenAI 兼容接口时:

LLM_API_TYPE=openai
LLM_MODEL=你的视觉模型
LLM_API_HOST=https://你的服务地址/v1
LLM_API_KEY=你的密钥

系统环境变量优先于 .env,程序界面中的修改只对当前运行生效。.env 不应提交到 Git 仓库,API Key 也不要写入公开配置或博客。

启动程序:

powershell -ExecutionPolicy Bypass -File .\run.ps1

run.ps1 会始终使用项目目录下 .venv 中的 Python。如果虚拟环境不存在,它会先自动执行安装脚本。

使用流程

实际操作只需要几步:

  1. 点击“选择目录”,指定待处理的照片或视频目录;
  2. 选择接口类型:ollama 或 openai;
  3. 配置 API 地址、视觉模型,以及需要时填写 API Key;
  4. 点击“测试连接”,确认服务可访问且模型名称正确;
  5. 点击“扫描目录”;
  6. 点击“AI 分析全部”;
  7. 检查并手工修改建议名称;
  8. 点击“应用重命名”,确认后完成批量处理。

分析过程采用顺序处理,不会同时把大量原图加载到内存中,更适合包含几十或几百个媒体文件的目录。正式重命名之前,所有建议都可以在表格中检查和修改。

当前版本的局限

目前版本仍有一些可以继续改进的地方:

  • 日期前缀暂时来自文件修改时间,还没有优先读取 EXIF 拍摄时间;
  • 视频只分析中间一帧,无法完整理解长视频内容;
  • 景点识别依赖视觉模型自身能力,模型可能只能描述画面而无法判断准确地点;
  • AI 生成的名称仍建议在应用前人工检查;
  • 不同 OpenAI 兼容服务对视觉消息格式和模型名称的支持程度可能存在差异。

未来可以继续增加 EXIF 拍摄时间、地理位置、多个视频关键帧、命名模板以及重复照片检测等功能。

项目源码

完整源码和安装说明已发布在 GitHub:

查看 GitHub 项目源码

如果你也有大量使用 IMG_XXXX.JPG 命名的旅行照片,希望这个工具能帮助你更高效地完成整理。

← Previous Post: Mindset 2026