上次在地铁上改图,手机里只有相册自带的裁切工具,身边又没有电脑,那种感觉真的很别扭。后来我把Photopea离线版部署到自己的Termux里,手机秒变一个随身图像处理工作台,不用连外部服务,纯本地跑,打开浏览器就能用。今天把这个部署过程完整记录下来,从环境准备到资源本地化、服务启动、常见坑位,一条线讲透,希望帮到想在手机或平板上折腾这类离线Web工具的朋友。
Photopea是一个跑在浏览器里的图像编辑器,界面布局和操作逻辑跟Photoshop非常接近,支持PSD、XD、Sketch这些格式,日常修图、切图、调色都能胜任。它本质是一套纯前端程序,核心逻辑通过WebAssembly在浏览器里执行,不需要后端参与,这给了我们离线部署的可能。所谓离线版,就是把Photopea的前端静态资源全部下载到本地,自己起一个轻量静态服务,让浏览器直接加载本地文件,整个过程不依赖公网,局域网内其他设备也能访问。我会从方案选型、环境准备、资源处理、服务启动和问题排查几个维度展开,正文里所有步骤我都实测过,代码和配置直接抄即可。
1. 方案设计与整体思路
1.1 定位:这件事到底解决什么
先明确一下这套东西适合谁。你需要在手机上处理图片,或者想给平板、旧笔记本做一个不依赖官方服务器的本地版Photopea,那这个方案就很对路。部署完成后,你在浏览器地址栏输入localhost:8080,就能进入完整的Photopea界面,新建画布、拖入图片、编辑图层,全部在本地完成。不联网也能用,传文件到局域网里,别人也能通过你的手机IP访问。
不做这项部署前,常用的在线版Photopea也有不错的体验,但它依赖官方服务器,网络波动、服务器维护、流量受限这些情况都会影响使用。而离线版把整套静态资源放进本机,相当于把一个完整的Web应用“搬”到自己的设备里,核心好处有三点:不受外部服务可用性影响,启动速度快,数据不出设备,隐私方面也更安心。
我不建议把这款工具当成Photoshop的完全替代品。它的强项是处理中等规模的图像编辑任务,PSD解析、图层调整、滤镜、蒙版这些常用能力足够扎实,但个别超复杂场景在手机浏览器上会有性能瓶颈。如果只是出差路上改个尺寸、调个色、抠个图,体验完全够用。
1.2 为什么用Termux来承载服务
Termux是Android系统上的终端模拟器,能够提供Linux环境,本质上是一个用户态的软件包管理器和命令执行环境,不需要root,也不用刷机。安装上Termux之后,你可以使用Linux里的常用命令、安装Python、Git、Nginx等开源工具,再借助这些工具把静态服务跑起来。
选择Termux而不是电脑端再开虚拟机,关键在于移动端的轻量性。手机本身有浏览器、有本地存储、有网络模块,Termux把这些能力整合到一起。再加上Termux支持获取唤醒锁和开机启动扩展,稳定性和自动化程度都有保障。整套方案完全可以在Android设备上闭环,不需要额外设备。
1.3 选型:静态文件服务器就够了
从架构角度看,Photopea离线版不需要数据库,不需要动态后端,不需要会话管理,它只需要一个最基本的HTTP静态文件服务器把index.html、JavaScript、CSS、字体、图片正确地喂给浏览器。那么选型的关键就落在运行环境里怎么最省事。
Termux官方源里有Python环境,自带python3 -m http.server,一行命令就能启动静态服务。这一方案的好处是零额外配置,Python解释器本身轻量,不需要编译安装,也天然支持绑定任意端口。相比之下,Nginx功能强大但体型较重,PHP内置服务器还要处理额外配置。考虑到场景是本地或小范围局域网访问,Python http.server足矣。我实际使用中也没有遇到性能问题,因为Photopea的资源加载是一瞬间的事,后续计算全部在浏览器本地完成。
这里要注意一个细节:Photopea离线版涉及跨域资源加载。浏览器默认会拦截file协议下的跨域请求,所以裸打开本地HTML文件通常白屏或只能看到部分界面。自建HTTP服务的本质就是提供合适的协议和响应方式,让所有资源来自同一个源,从而绕开浏览器的跨域限制。这也是整个部署里必须起服务、不能直接点开文件的根本原因。
2. 环境准备与依赖安装
2.1 Termux版本与存储权限
开始之前先确认Termux是从官方渠道安装的,不要用各种渠道的修改包。打开Termux后第一件事是把软件包管理器更新到最新状态,我这里使用的包管理器是pkg,它是apt的一套封装,做过目录适配,比直接用apt省心。
pkg update pkg upgrade按提示确认安装,整个过程会刷新软件源索引并升级已有组件,耗时取决于网络情况。升级完成之后执行:
termux-setup-storage这一步会触发Android系统的存储权限弹窗,选择允许,之后Termux就能访问手机公共目录,通常挂载在/storage/emulated/0下。后面我们需要把下载的Photopea资源包放到方便管理的目录,所以存储权限是必须的。
2.2 更换软件源的必要性
Termux默认的软件源在部分地区访问速度不理想,下载依赖时可能会非常煎熬。解决方式是把软件源切换到国内高校维护的镜像,这里用的是清华源。顺手吐槽一下,很多人卡在“pkg update进度条不动”其实都不是网络配置问题,单纯就是源太远。
切换镜像前先备份原配置,避免手滑改错:
cp $PREFIX/etc/apt/sources.list $PREFIX/etc/apt/sources.list.bak然后编辑源文件,把官方源地址替换为清华镜像地址。Termux新版用的是sources.list文件,旧版本可能在sources.list.d目录下,根据自己实际版本处理。替换后执行:
pkg update看到下载速度明显起来就说明切换成功。这里多说一句,换源只是换包下载通道,不影响任何上层业务,也不涉及其他网络策略。
2.3 安装依赖清单
下面列出部署要用的软件包,不需要全部都装,按需来即可。我的核心依赖是Python和Git,curl和unzip用于下载解压,openssh用于电脑和手机之间传文件,可选项按需加。
| 软件包 | 用途 | 安装命令 |
|---|---|---|
| python | 提供python3 http.server服务 | pkg install python |
| git | 拉取更新资源 | pkg install git |
| curl | 命令行下载文件 | pkg install curl |
| unzip | 解压资源包 | pkg install unzip |
| openssh | 可选,电脑-手机传文件 | pkg install openssh |
| tmux | 可选,保活会话 | pkg install tmux |
安装时建议一次性执行:
pkg install python git curl unzip -y如果后面要传文件再单独装openssh,平时用不到可以省点空间。
2.4 验证基础环境
装完依赖后做个快速验证,分别检查Python版本和Git是否正常:
python --version git --version这里有个细节:Termux里运行Python的命令直接是python,不是python3,因为Termux仓库的包名和符号链接已经处理过,和常规Linux发行版略不同。看到输出版本号之后,基础环境就绪,接下来处理Photopea资源本身。
3. Photopea离线资源获取与本地化
3.1 获取源码包
Photopea的发布资源可以从GitHub的官方仓库获取。项目仓库的Release页面会提供编译后的产物,里面包含index.html和一系列静态资源文件。推荐先在电脑上下载好zip包,再通过openssh的scp命令推到手机Termux的home目录,这样下载速度更快。如果你只在手机端操作,也可以直接在Termux里用curl下载。
Termux里下载的参考命令:
curl -L -o photopea.zip "替换为实际的release包下载地址"下载完成后在合适目录解压,例如:
unzip photopea.zip -d photopea3.2 源码目录结构
解压后的目录结构大致包含:
photopea/ ├── index.html ├── p.js ├── css/ ├── fonts/ ├── js/ └── resources.jsonindex.html是入口页面,p.js是主逻辑代码,css和js目录存放界面样式和功能脚本,fonts目录负责字体,resources.json是资源映射清单。这些文件加起来通常不超过几十兆,对手机存储来说没什么压力。
关于版本选择,我建议获取官方最新的稳定发布版,而不是开发分支。开发分支虽然会提前引入新特性,但也可能伴随不稳定的问题,离线部署的诉求本来就是稳定可用,没必要追求最新。
3.3 外链资源本地化
这一步是整个部署的核心,也是“离线版”三个字的关键所在。直接解压后的Photopea源码里,部分资源引用指向第三方CDN域名,比如字体、库文件、图标等。在线状态下这些引用没有问题,但一旦断网,页面就会因为加载不到资源而表现为排版错乱、图标丢失甚至直接白屏。
处理思路很明确:扫描页面里所有外部请求,把外部资源下载到本地,再把引用地址从CDN域名替换为本地相对路径。这一步可以手动做,也可以写一个小脚本自动处理。我第一次是动手改几个关键文件,后面发现资源多的版本一个个改太累,改用脚本扫描。
脚本的核心逻辑可以这样简述:读取index.html和resources.json,提取所有https://开头的资源地址,去重后逐个下载到对应目录,同时按映射关系改写页面中的URL。这个思路同样适用于其他前端应用的离线化,通用性很强。脚本不复杂,Python几十行就能写完,注意处理URL里的路径层级和文件名特殊字符。
不要试图保留CDN域名而只靠缓存。浏览器缓存受容量、过期策略、隐私模式影响,缓存不可控,一旦失效整个界面就打回原形。本地资源替换是离线部署最稳妥的一条路。
3.4 文件权限与放置规范
资源目录处理好之后,放在固定位置方便管理。我习惯放在~/photopea下,并确保目录及其内部文件对当前用户可读。“把文件放在什么位置”看似小事,实际会影响后续服务启动的路径记忆成本。统一放在~/下,每次启动服务只需要记住一个路径。
如果后面要支持写入功能,比如Photopea里导出图片到本地,那还要考虑存储目录的权限问题。Photopea本身通过浏览器下载文件,这部分逻辑挂在Android下载目录下,Termux侧不需要额外授权。
4. 核心部署与启动服务
4.1 一行命令启动静态服务
完成资源本地化后,进入photopea目录,执行:
cd ~/photopea python -m http.server 8080 --bind 0.0.0.0然后打开手机浏览器,访问http://localhost:8080,就能看到Photopea的编辑界面。--bind 0.0.0.0表示监听所有网络接口,这样不仅本机能访问,局域网内其他设备也能通过你的手机IP访问。如果不加这个参数,默认只监听本地回环地址,其他设备就进不来。
默认端口8080可以和常见端口区分开,避免跟其他服务冲突。如果8080被占用了,换一个高位端口即可,比如8090。
4.2 编写启动脚本
每次手动敲一大串命令太麻烦,我写了一个start.sh脚本,存到~/目录下,直接用bash start.sh来启动:
#!/data/data/com.termux/files/usr/bin/bash cd ~/photopea exec python -m http.server 8080 --bind 0.0.0.0给脚本加执行权限:
chmod +x ~/start.sh之后随时想启动,只要运行~/start.sh就行。如果你想在后台运行,不占用当前终端,可以用:
nohup ~/start.sh > ~/photopea.log 2>&1 &这样即使退出Termux窗口,服务也能继续跑。日志输出到photopea.log文件,后续排查问题能派上用场。
4.3 局域网访问配置
手机和电脑连同一个WiFi时,通过手机的局域网IP就能访问。查看IP地址的命令:
ifconfig或者使用更简洁的方式:
ip -4 addr show | grep inet常见的输出形如192.168.x.x。拿到IP后,在电脑浏览器地址栏输入http://192.168.x.x:8080,就能打开同一套Photopea界面。这个能力非常实用,比如你把手机固定在一个位置当小型工作站,用电脑鼠标键盘去操作,体验比直接在触屏上精细修图舒服很多。
这里有一个实际经验:Android热点默认可能会启用客户端隔离,如果你用手机开热点给电脑上网,部分机型的热点设置里会限制终端间互访,导致电脑连上了WiFi却无法访问手机服务。遇到这种情况,到热点设置里关闭客户端隔离,或者改让手机连接路由器WiFi而不是开热点。
4.4 唤醒锁与服务保活
Termux被Android系统杀后台是这个方案里非常影响体验的问题。如果你在Termux里跑着服务,然后切到浏览器使用Photopea,系统会在内存紧张时结束Termux进程,服务随即断开。解决方式分两步处理。
第一步,在Termux里主动请求唤醒锁:
termux-wake-lock命令执行后,Termux会持有CPU唤醒锁,降低被系统挂起的概率。第二步,把Termux加入系统的电池优化白名单,在系统设置里找到电池或后台管理,把Termux设置为不限制后台运行。部分机型还要在应用详情里打开“后台弹出界面”或“自启动”权限。
想要真正实现开机自动启动服务,可以安装Termux:Boot插件,把启动脚本放到~/.termux/boot/目录下,让服务在手机启动后自动拉起。这套组合在日常使用中稳定性非常好,我实测连续跑几天不杀后台是没问题的。
5. 常见问题与排查技巧
5.1 浏览器打开白屏
白屏是高频问题,大概率原因有两个:一是启动服务时工作目录不对。python -m http.server是在当前目录提供文件服务,如果你在~目录启动,它只会暴露~下的文件,而Photopea文件在~/photopea子目录里,浏览器访问根路径时找不到index.html,自然白屏。解决方式就是先cd到photopea目录再启动。
二是跨域问题没解决。直接双击index.html用file协议打开,浏览器会阻止跨域脚本请求,结果也是白屏或者部分功能不可用。回到用http服务访问的路径上就行。
如果确认以上两点都没问题,看服务日志,Python http.server会把每个请求打印出来,哪条请求返回404就说明对应的资源缺失,回目录里补上就好。
5.2 字体图标显示方框
字体图标全是方框,说明字体文件加载失败。Photopea界面里用了自定义字体图标和部分特殊字体库,这些资源原始引用可能是CDN地址。离线部署时必须把所有字体请求全部下载到本地并替换路径。排查时可以打开浏览器的开发者工具,切到Network面板,过滤Font类型,排查哪个字体请求失败,再回到本地资源目录里看对应文件是否存在。
想省事的话,直接在部署前用我前面提到的脚本统一处理外部资源,一次性把字体、库文件、图片全部本地化,比逐个排查快得多。
5.3 保存文件失败
Photopea在浏览器里保存文件依赖浏览器下载能力。Android端使用Chrome或系统浏览器访问时,下载动作会触发系统下载管理器,这个过程和服务器端没有关系。如果你发现保存按钮点了没反应,先检查浏览器是否禁用了下载权限,或者存储权限是否授权给浏览器应用。
另外Photopea还有自动保存草稿的功能,草稿数据存在浏览器的IndexedDB里,跟服务器无关。如果清理过浏览器数据,之前未导出的草稿会一并删除,这个不是部署问题,但容易让人误以为数据丢了。
5.4 内存不足与卡顿
手机浏览器虽然能运行WebAssembly,但内存资源相对有限。Photopea打开超大PSD文件时,内存占用会急剧上升,表现为界面卡顿或浏览器直接崩溃。实践中建议把单个处理的图片或PSD控制在合理范围内,普通修图一两百兆字节以内的文件通常没问题,再大的就交给电脑处理吧。
另外一个提升体验的做法是在手机浏览器里开启桌面版网站模式。Photopea的界面在手机窄屏下确实挤,开启桌面模式后布局接近电脑端,菜单和工具栏完整展示,操作顺手很多。开启方式各个浏览器略有不同,Chrome系在设置里勾选“桌面网站”即可。
5.5 问题排查速查表
下面把常见问题整理成表格,方便直接对照排查。
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 页面白屏 | 启动目录不对 | 先cd到photopea目录再启动服务 |
| 页面白屏 | 使用file协议直接打开 | 改为http://localhost:8080访问 |
| 资源404 | 外链资源未本地化 | 扫描并替换所有外部资源引用 |
| 图标方框 | 字体文件缺失 | 检查font资源加载是否完整 |
| 保存失败 | 浏览器下载权限被禁 | 授权浏览器存储权限 |
| 服务自动断开 | 系统杀后台 | 使用termux-wake-lock并加入电池白名单 |
| 局域网访问失败 | 端口未绑定0.0.0.0 | 启动命令加--bind 0.0.0.0 |
| 局域网访问失败 | 热点客户端隔离 | 关闭热点隔离或改用路由器WiFi |
5.6 备份与版本更新
离线版部署完成后,整个photopea目录就是全部家当。建议把目录打包备份一份,放到手机公共存储或者传到电脑上,万一哪天Termux数据被清理,几分钟就能恢复环境。
打包命令:
tar -czf photopea-backup.tar.gz ~/photopea之后要更新版本,只需要重新下载新版资源包,再次执行外部资源本地化脚本,替换旧目录即可。服务和脚本都不用大改,非常省心。
6. 一点实际使用体会
整套方案做完之后,我把它当作一个随身图像处理工具来用。不占额外存储,打开浏览器就进入编辑界面,局部修改图片、导出成果,整个过程数据都在本机流转。如果你有旧手机闲置,完全可以部署一套放在固定位置,通过局域网给其他设备共享访问,旧设备重获新生。
我和这个方案磨合了一段时间,最大的体会是:不要在手机屏幕上做精细的像素级操作,这是触屏设备的天花板,不是工具的问题。配一个蓝牙鼠标,或者直接用局域网从电脑访问,体验会有质的飞跃。整套部署链路其实不复杂,把静态资源本地化这个核心点吃透以后,换个其他纯前端项目也能举一反三。以后在Termux里开个端口就能拥有一套本地Web工作站,这种感觉还是挺上头的。