5小时打造桌面AI应用:用Flutter从零构建 Real-ESRGAN-GUI 的完整架构指南
【免费下载链接】Real-ESRGAN-GUILovely Real-ESRGAN / Real-CUGAN GUI Wrapper项目地址: https://gitcode.com/gh_mirrors/re/Real-ESRGAN-GUI
Real-ESRGAN-GUI 是一款用 Flutter 从零构建的跨平台桌面 AI 图像放大工具,它把 Real-ESRGAN 与 Real-CUGAN 两套 ncnn Vulkan 命令行引擎封装成简洁的图形界面,让你无需敲任何命令,就能一键把低分辨率图片和插画高清放大 2~4 倍。本文将完整拆解它的架构设计:目录组织、窗口启动流程、双引擎 Tab 页面、可复用组件划分,以及如何用 Dart 进程调用实现 AI 放大与实时进度条,帮你用同样思路在 5 小时内做出自己的桌面 AI 应用。
💡 Real-ESRGAN-GUI 是什么?
一句话概括:一个把命令行 AI 放大工具变成友好 GUI 的桌面壳应用。它的核心能力包括:
- 🖼️双引擎支持:内置 Real-ESRGAN(通用 + 插画)与 Real-CUGAN(插画特化、可降噪)两个引擎及其全部模型文件
- 📂单文件 / 文件夹批量两种输入模式,支持一键批处理整个目录
- 🎛️ 可选模型、放大倍率(2x/3x/4x)、降噪等级、输出格式(jpg/png/webp)
- ⏳ 实时进度条与一键取消,出错时弹出可复制的错误日志
- 🌍4 语言国际化(中文、英文、日文、乌克兰文)
- 🪟 同时支持Windows 10+ 与 macOS(Intel 与 Apple Silicon)
整个项目 v1.0.0 的作者仅用 5~6 小时就完成,说明"GUI 封装"类桌面 AI 应用完全可以快速落地。
📁 项目目录结构总览
先看整体骨架,理解它的分层思路是读懂代码的第一步:
Real-ESRGAN-GUI/ ├── lib/ # 全部 Dart 应用源码 │ ├── main.dart # 入口:窗口尺寸/位置/标题 + 国际化初始化 │ ├── utils.dart # 公共工具:引擎路径、表单校验、文件配对 │ ├── components/ # 6 个可复用 UI 组件 │ │ ├── io_form.dart # 文件/文件夹 双模式输入输出表单 │ │ ├── model_type_dropdown.dart │ │ ├── upscale_ratio_dropdown.dart │ │ ├── output_format_dropdown.dart │ │ ├── denoise_level_dropdown.dart │ │ └── start_button_and_progress_bar.dart │ └── views/ # 两个引擎的 Tab 页面 │ ├── real_esrgan_tab_page.dart │ └── real_cugan_tab_page.dart ├── assets/ # 随应用打包的二进制与模型 │ ├── realesrgan-ncnn-vulkan/ # Real-ESRGAN 引擎 + models/ │ ├── realcugan-ncnn-vulkan/ # Real-CUGAN 引擎 + 3 套模型 │ └── translations/ # 4 个语言 JSON ├── windows/ # Windows 平台层(CMake + runner) ├── macos/ # macOS 平台层(Xcode 工程) └── pubspec.yaml # 依赖与资源声明设计要点:AI 引擎是"数据",UI 是"应用"。二进制可执行文件和模型全部放在 assets/ 下随应用分发,Dart 代码只负责拼参数、启动进程、读日志——这种"胖 assets + 瘦代码"的模式是封装 CLI 工具最快的架构。
🚀 应用启动流程:窗口、DPI 与国际化
入口在 lib/main.dart#L15-L68,启动顺序非常清晰:
WidgetsFlutterBinding.ensureInitialized()完成 Flutter 绑定初始化EasyLocalization.ensureInitialized()初始化国际化- 通过
getCurrentScreen()读取屏幕信息,按DPI 缩放计算窗口最小尺寸(780×694),并居中显示窗口;macOS 下特殊地把缩放强制设为 1 倍 setWindowFrame()+setWindowMinSize()设置窗口位置与下限,setWindowTitle()设置标题runApp()启动,外层包一层EasyLocalization,指定语言文件目录assets/translations与支持的语言列表(ja-JP、en-US、zh-CN、uk),回退语言为英文
窗口尺寸依赖来自window_size插件(声明于 pubspec.yaml#L48-L51),一行代码就能解决桌面应用"窗口多大、放在哪"这类原生问题。
🗂️ 双引擎架构:一个壳 + 两个 Tab
主页面 MainWindowPage 是理解整体架构的关键:
- 用
TabController管理Real-ESRGAN / Real-CUGAN两个 Tab,切换时还会动态改变标题栏颜色(绿色 ↔ 浅蓝),视觉上区分两个引擎 TabBarView分别挂载 RealESRGANTabPage 与 RealCUGANTabPageinitState中还有个贴心细节:启动时请求最新 tag 版本,发现有新版本就弹出更新提示对话框
两个 Tab 页面的结构几乎同构(表单 + 下拉选项 + 开始按钮),这正是它 5 小时能做完的核心原因——页面只是组件的编排者,所有逻辑沉在组件与工具函数里。
🧩 六个可复用组件:把表单拆小
| 组件 | 源码位置 | 职责 |
|---|---|---|
| 输入输出表单 | io_form.dart | 文件/文件夹双模式切换,自动推导输出路径 |
| 模型选择 | model_type_dropdown.dart | 按引擎动态生成模型下拉项 |
| 放大倍率 | upscale_ratio_dropdown.dart | 2x/3x/4x 选项,随模型联动可用项 |
| 输出格式 | output_format_dropdown.dart | jpg / png / webp |
| 降噪等级 | denoise_level_dropdown.dart | 按"模型 × 放大倍率"组合灰置无对应模型的选项 |
| 开始按钮+进度条 | start_button_and_progress_bar.dart | 处理中变红色"取消"按钮,下方线性进度条 |
其中最有设计感的是 denoise_level_dropdown.dart#L28-L59:它根据当前模型与放大倍率动态判断每个降噪项是否可用(例如models-pro不支持 1x/2x 降噪就置灰),把"后端能力的差异"翻译成"UI 的可用性",用户永远不会选到不存在的组合。
⚙️ 核心链路:用 Dart 调用 AI 放大引擎
这是整个项目技术含量最高的部分,完整实现见 lib/views/real_esrgan_tab_page.dart#L68-L223,流程如下:
- 定位引擎二进制:getUpscaleAlgorithmExecutablePath() 按平台拼接路径——Windows 下是
data/flutter_assets/assets/,macOS 下则藏在.app的Frameworks/App.framework/.../flutter_assets/assets/深处,并自动补.exe后缀 - 表单校验:validateIOForm() 统一处理"未选文件 / 路径非法 / 已存在需确认覆盖"等边界情况,失败则直接中断
- 生成文件配对:getInputFileWithOutputFilePairList() 在文件夹模式下用
glob匹配jpg/jpeg/png/webp,为每张图自动生成"保留目录结构的输出路径" - 启动进程:
Process.start(可执行文件, ['-i', 输入, '-o', 输出, '-n', 模型, '-s', 倍率, '-f', 格式], workingDirectory: 引擎所在目录)——注意工作目录必须设为引擎目录,否则 macOS 下会因找不到models/而崩溃 - 解析进度:监听
process.stderr,用正则([0-9]+\.[0-9]+)%提取进度日志,按"已完成张数 × 每张照片占比 + 当前照片进度"合成总百分比,setState刷新进度条 - 可控可恢复:再按一次按钮即
process.kill()取消;进程非 0 退出时,把累积的错误日志放进可选择的 SnackBar 展示给用户
仅靠dart:io的ProcessAPI,就把一个需要 Vulkan GPU 驱动的 AI 引擎接进了图形界面——不写一行 FFI,不碰一个插件。
🌍 国际化:JSON 驱动的 4 语言支持
界面文案零硬编码,全部走easy_localization:
- 语言文件位于 assets/translations/zh-CN.json,另有 en-US、ja-JP、uk 三份
- Key 按语义分组:
label.*(按钮标签)、model.*(模型说明)、denoise.*(降噪选项)、scale.*(倍率)、format.*(格式)、message.*(提示语,{}占位支持插值) - 动态项也很优雅:下拉选项的 key 用枚举名拼出来,如
'model.RealESRGAN.${modelType}',新增模型只需加一行翻译,无需改 UI 代码
🛠️ 自己动手:5 小时复刻一个桌面 AI 应用
基于本项目的架构,你复刻同类应用的路线图如下:
- 建工程:
flutter create后只保留windows/与macos/两个平台目录(本项目对应 windows/ 与 macos/ 原生工程层) - 装依赖:对照 pubspec.yaml,核心只有
window_size(窗口控制)、file_picker/file_selector(文件对话框)、easy_localization(i18n)、glob+path(文件遍历) - 备 assets:把目标 CLI 引擎、模型、语言 JSON 放入
assets/并在flutter:段声明——资源声明见 pubspec.yaml#L76-L84 - 写入口:照 main.dart 的 5 步设置窗口与国际化
- 搭组件:拆出"输入输出表单 + 若干下拉 + 开始按钮/进度条",参考 lib/components/
- 接引擎:用
Process.start调起二进制,解析 stderr 更新进度,出错展示日志
💡 经验总结:GUI 封装类桌面 AI 应用的 80% 工作量在表单、校验与错误处理,而这部分 Flutter 的 Material 组件能几乎全部复用。先跑通"单文件 → 单进程 → 进度条"的最小闭环,再扩展文件夹批处理与多引擎,是最稳的推进节奏。
✅ 写在最后
Real-ESRGAN-GUI 用一个周末时间证明了一个事实:借助 Flutter 桌面端与"二进制进 assets"的封装思路,把 Real-ESRGAN / Real-CUGAN 这样的命令行 AI 工具变成人人可用的图形界面,真的只需要一个下午。项目遵循 MIT 协议(见 License.txt),其"瘦代码 + 胖资源"的目录结构、组件化表单与进程进度解析方案,都值得你直接借鉴到自己的桌面 AI 应用中。
【免费下载链接】Real-ESRGAN-GUILovely Real-ESRGAN / Real-CUGAN GUI Wrapper项目地址: https://gitcode.com/gh_mirrors/re/Real-ESRGAN-GUI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考