项目起点
Lolicon API 的官方文档本身就是一个功能完整的 Demo 页面。左边是参数面板,右边是图片网格,支持 R18 分级、数量选择、关键词搜索、标签 AND/OR 组合、图片代理设置、预设管理、批量下载 ZIP、大图预览。这个页面是用纯 HTML/CSS/JS 写的,没有任何框架依赖。
我当时想,如果能把它做成一个独立的桌面应用就好了,不用每次打开浏览器,可以放在任务栏上随时用。
为什么选 Electron
我对桌面开发的经验几乎为零。Qt 要学 C++ 和信号槽机制,WPF 要学 C# 和 XAML,这些学习成本对我来说太高了。Electron 的最大优势是我可以把已有的网页代码直接搬过来,不需要重写任何界面逻辑。
技术栈就是 HTML、CSS、JavaScript,加上 Node.js 提供的主进程能力。API 请求、JSON 解析、图片渲染、ZIP 打包,这些在浏览器里都能正常工作,套进 Electron 里理论上也不会有问题。
项目初始化
先用 npm 初始化项目:
代码登录后可见
生成的 代码登录后可见 需要手动修改,添加入口文件和启动脚本:
代码登录后可见
然后安装依赖:
代码登录后可见
这个过程比较漫长,Electron 的二进制包有好几十 MB,国内网络下载经常超时。我后来换了淘宝镜像才顺利装完。
主进程 main.js
Electron 的架构是主进程加渲染进程。主进程负责创建窗口、处理系统事件、和操作系统交互。渲染进程就是网页,跑在 Chromium 里。
代码登录后可见
代码登录后可见 是关键,这样我才能用 HTML/CSS 自定义标题栏。但这也意味着我需要自己实现窗口拖动、最小化、最大化、关闭功能。
预加载脚本 preload.js
为了安全,Electron 建议不要在渲染进程中直接使用 Node.js API。预加载脚本是一个中间层,把主进程的能力安全地暴露给渲染进程。
代码登录后可见
主进程中的窗口控制
在 代码登录后可见 中处理来自渲染进程的窗口操作请求:
代码登录后可见
自定义标题栏 HTML
因为隐藏了系统标题栏,我需要在 HTML 顶部自己画一个:
代码登录后可见
CSS 中关键的设置:
代码登录后可见
代码登录后可见 让整个标题栏区域可以拖拽,但按钮需要 代码登录后可见 来排除在外。
标题栏按钮的事件绑定
在 JavaScript 中绑定按钮事件:
代码登录后可见
Content Security Policy 问题
原来的 HTML 文件里有一个比较严格的 CSP meta 标签。在浏览器环境下这是好的安全实践,但在 Electron 里,默认的 代码登录后可见 协议加载本地文件时,CSP 可能会阻止网络请求。
代码登录后可见
关键点:代码登录后可见 必须允许 代码登录后可见,因为所有色图数据都是从这个 API 获取的。代码登录后可见 必须允许 代码登录后可见 和 代码登录后可见,因为图片链接来自不同的代理服务器。
图片代理和跨域
Lolicon API 返回的图片 URL 指向 Pixiv 的原始地址 代码登录后可见,这个地址有防盗链。API 提供了代理参数 代码登录后可见,可以用 代码登录后可见、代码登录后可见 等反代服务来绕过防盗链。
在我的应用中,用户可以在侧边栏选择或自定义代理地址。默认值是 代码登录后可见。
代码登录后可见
图片加载问题
在浏览器中,代码登录后可见 可以直接加载远程图片。但在 Electron 中,如果 CSP 设置不当,图片可能会被阻止。
我在开发过程中遇到过一个很坑的问题:图片在开发者工具中显示加载成功,但在页面上不显示。排查了很久才发现是 CSS 的 代码登录后可见 和容器的固定宽高比配合有问题。有些图片的原始比例和容器不匹配,被裁剪掉了重要内容。
后来改成 代码登录后可见,配合 代码登录后可见 限制最大高度:
代码登录后可见
批量下载 ZIP
这个功能实现起来比我想象的复杂。一开始我用了 JSZip 的 CDN:
代码登录后可见
但 Electron 环境下,CDN 有时候加载失败,导致批量下载按钮点击后没反应。而且依赖外部 CDN 总是不太可靠。
后来我改成了纯 JavaScript 手动构建 ZIP 格式。ZIP 文件的结构其实不复杂:每个文件前面是 Local File Header(包含文件名、CRC32、文件大小等),后面跟文件数据。所有文件后面是 Central Directory(重复一遍文件信息),最后是 End of Central Directory Record。
代码登录后可见
文件名用 UTF-8 编码,设置 代码登录后可见 的 bit 11。这样 Windows 11 和 macOS 的资源管理器都能正确显示中文文件名。
下载文件的命名
Lolicon API 返回的数据里包含作品的标题、PID、扩展名等信息。我用这些信息来给下载的文件命名:
代码登录后可见
但是标题里经常有特殊字符,Windows 文件名不允许 代码登录后可见 这些字符。我需要做清理:
代码登录后可见
预设管理系统
预设功能让我可以把常用的搜索参数保存下来,一键切换。数据用 代码登录后可见 持久化:
代码登录后可见
侧边栏滚动问题
侧边栏参数很多的时候,如果窗口不够高,下面的搜索按钮就被挤出屏幕了。我一开始设置了 代码登录后可见,但发现滚动条样式和整体设计不搭。
自定义滚动条样式:
代码登录后可见
Electron 使用 Chromium 内核,所以 代码登录后可见 伪类是生效的。
URL 实时预览
侧边栏底部有一个 URL 预览区,显示当前参数构建的完整 API 地址。这个功能在调试时很有用,可以直观地看到参数变化对 URL 的影响。
代码登录后可见
打包和分发
用 代码登录后可见 打包 Windows 版本:
代码登录后可见
打包命令:
代码登录后可见
打包完成后 代码登录后可见 目录下会生成:
- 代码登录后可见,安装包,约 80MB
- 代码登录后可见 文件夹,是解压后的绿色版
安装后整个应用目录大约 250MB。说实话,对于一个图片浏览工具来说,这个体积确实有点尴尬。光是 Electron 的运行时就有 150MB 以上,加上 Chromium 的渲染引擎。
最后的问题
Electron 版本用起来很流畅,功能齐全,开发也快。但每次看到安装包 250MB 的体积,我都觉得不太对劲。而且启动时要加载整个 Chromium,内存占用大概 300MB 左右。对于 16GB 内存的电脑来说问题不大,但我总觉得一个看图工具不应该这么重。
这也是为什么我后来去折腾了 EUI NEO 那个 C++ 框架。同样的功能,C++ 版本编译出来只有十几 MB,内存占用也小很多。当然,开发成本也高了很多,光环境配置就花了我大半天。
总结
Electron 适合快速出活。如果你已经有网页版,半天就能搞出一个能用的桌面版本。而且调试方便,打开 DevTools 就能看到网络请求和控制台输出。缺点是体积大、内存占用高,不适合对资源敏感的场景。
如果让我重新选,我可能还是会先上 Electron 快速验证想法,等确定要长期维护了再考虑重构成原生应用。毕竟,先跑起来比什么都重要。