> ## Content Index
> Fetch the complete content index at: https://yinguobing.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# 给 IOPaint 加了图像压缩功能，聊聊这个开源修图工具
- URL: https://yinguobing.com/blog/iopaint-image-compression/
- Published: 2026-05-28T13:06:52.000Z
- Updated: 2026-05-28T14:04:21.000Z
- Author: 小黑
- Tags: 开源工具

最近花了点时间研究了一个叫 **IOPaint** 的开源项目，还顺手给它加了个图像压缩的功能。这篇文章记录一下这个工具本身，以及做了些什么。

## IOPaint 是什么

IOPaint 是一个完全免费开源的 AI 图像编辑工具。简单说，你涂抹掉图片上不想要的东西，它用 AI 给你补上。水印、路人、杂物，涂掉就行。

底层用的是各种 SOTA 的 AI 模型：

- **LaMA**：快速擦除，处理普通物体/水印/缺陷
- **Stable Diffusion inpainting**：更智能的填充，适合复杂场景
- **PowerPaint**：不只是擦除，还能替换物体、扩展画布
- **AnyText**：在图上写字

架构很干净：FastAPI 后端 + React 前端，PyTorch 做推理，支持 CPU / CUDA / MPS。

项目在 GitHub 上 21k+ stars，社区活跃，持续更新。

## 为什么要折腾它

IOPaint 本身已经很能打了，但有个问题——**输出的图片太大了**。

它的默认质量是 95/100，而且保持原格式输出。如果你处理的是 PNG 原图，输出的 PNG 可能几 MB 甚至十几 MB。如果只是去个水印发个网页，完全没必要那么大。

所以我想加一个**导出压缩**的功能：让用户选择输出格式（JPEG / WebP / AVIF / PNG），控制质量，甚至无损压缩。处理完后直接拿到体积合适的文件，省掉「导出→再压缩」的步骤。

## 技术选型

核心是图像压缩库的选择。调研了几个方案：

| 方案              | 说明                                        |
| --------------- | ----------------------------------------- |
| **Pillow 原生**   | IOPaint 已有，但 JPEG/WebP 压缩率一般              |
| **Squoosh CLI** | Google 出品，效果好，但得装 Node.js                 |
| **imagecodecs** | Python 库，封装了 mozjpeg/libwebp/libavif，一步到位 |

最终选了 `imagecodecs`。纯 Python 包，底层就是 Squoosh 用的那套 C 库（mozjpeg、libwebp、libaom），压缩效果完全一样。

就是有个坑：`imagecodecs` 的版本和 API 有点混乱。VERSION.txt 翻了好久才发现，`imwrite(None, data)` 不行，得用 `jpeg_encode()`、`webp_encode()` 这种函数。

如果你的环境里没有 imagecodecs，代码自动退回到 Pillow，不会报错。

## 前端改动

IOPaint 的前端是 React + Vite + shadcn/ui，代码写得不错，接入起来很顺畅。在设置面板里加了一个 **Compress** 标签页：

- **开关**：启用/禁用压缩
- **格式选择**：JPEG（兼容性最好）、WebP（平衡）、AVIF（最小体积）、PNG（无损）
- **质量滑块**：1-100
- **无损开关**：WebP/PNG 下可选

设置会持久化，保存在浏览器的 zustand store 里，下次打开还在。

## 部署体验

Docker 构建花了不少时间，主要是 PyTorch 太大了（2.2GB）。改成了多阶段构建：

1. **base 阶段**：CUDA 12.1 + PyTorch 2.1.2 + imagecodecs
2. **frontend 阶段**：Node 20 Alpine 编译前端 TypeScript
3. **final 阶段**：合并后安装 IOPaint

镜像总大小约 4GB，主要是 PyTorch 和 CUDA runtime 占了绝大部分。

启动一条命令：

```bash
docker run -d --gpus all -p 8080:8080 --name iopaint iopaint:gpu-compress

```

RTX 3090 上推理一张 1080p 图片的 LaMA 擦除大约 200ms。

## 代码仓库

改动已推送到 GitHub： https://github.com/yinguobing/IOPaint

改了 10 个文件，新增 330 行。如果你想在本地跑，直接拉代码用 Docker 构建就行。

## 几点感想

1. **Python AI 工具的依赖管理是痛点。** 一个 IOPaint 装下来几十个包，PyTorch + transformers + diffusers + gradio，哪个都不小。Docker 是唯一靠谱的交付方式。
2. **imagecodecs 是个好库，但文档太差。** 好在源码可读，对着测试用例写调用比看文档快得多。
3. **开源项目改起来比想象中舒服。** IOPaint 的代码结构清晰，前后端分离，插件体系完善，要扩展功能不需要大规模重构。
4. **AI 修图 + 压缩是一个很自然的组合。** 处理图片的最终目的是使用，压缩应该是一站式体验的一部分，而不是额外步骤。