ARTICLE · 1035927
我用 AI 写了个证件照小工具:不装软件、不传服务器,打开网页就能用
预计阅读时间:约 6 分钟
一句话说清:一个单文件网页,AI 模型直接在浏览器里跑——自动识别人脸、摆正角度、抠图换底色、按标准尺寸裁切、自动排版铺满相纸;照片全程不上传任何服务器。打开即用:https://peterinblue.github.io/demo/01/
一、起因:为了一张一寸照,我决定自己做个工具
事情的起点特别小。
家里长辈要办个证件,需要一寸白底照;我自己报个名,要二寸蓝底;翻翻旧相册,找到的电子照要么像素糊得没法用,要么底色不对。跑一趟照相馆不算难事,但对长辈来说,出门、排队、等出片、再去取,一套流程下来大半天就没了。
那用网上的在线工具呢?试了几个,问题也很明显:
1. 照片要上传到别人的服务器。证件照是人脸加身份信息的组合,属于最敏感的一类个人照片。传上去之后存哪、存多久、给谁看,用户完全不知道。
2. 导出环节处处是墙。免费预览、下载要钱、加个水印、给个低分辨率版本,套路很熟练。
3. 底色和尺寸往往还得手动试。抠图边缘毛毛躁躁,蓝底看着发灰,尺寸参数还得自己算毫米和像素的换算。
既然这几件事规则是明确的、技术上是可解的,那不如自己做一个:免费、无水印、照片不出本机、手机电脑都能用。
于是有了这个小工具。
二、它现在能做什么
整个流程被压缩成四步,不需要任何教程:
1. 上传或拍照——手机可以直接调用摄像头现场拍,电脑上就拖一张图进去。
2. AI 自动处理——识别出人脸和人体,自动把歪掉的角度摆正,然后抠掉背景。
3. 一键换底色——默认纯白底,也可以切蓝底、红底、绿底、自定义颜色,或者要透明背景导 PNG。
4. 选尺寸、自动排版、下载——按 300dpi 出图,也可以一键铺满整张相纸,拿去冲印。
支持的尺寸覆盖了国内常见场景:
规格 | 尺寸(mm) | 输出像素(300dpi) |
一寸 | 25 × 35 | 295 × 413 |
小一寸 | 22 × 32 | 260 × 378 |
大一寸 | 33 × 48 | 390 × 567 |
二寸 | 35 × 49 | 413 × 579 |
小二寸 | 35 × 45 | 413 × 531 |
大二寸 | 35 × 53 | 413 × 626 |
护照 / 签证 | 33 × 48 | 390 × 567 |
身份证 | 26 × 32 | 307 × 378 |
正方形(2 寸) | 51 × 51 | 602 × 602 |
简历照 | 25 × 35 | 295 × 413 |
尺寸之外还能选排版:不排版只出单张,或者一键铺满 5 寸相纸(127×89mm)、6 寸相纸(152×102mm)、A4(210×297mm),并可选加裁剪参考线。排版这一步以前最烦人——自己想在一张 6 寸相纸上摆下 8 张一寸照、算间距和留白,纯手工试错,现在点一下就好。
如果 AI 的自动定位不合你意,所有参数都能手动接续微调:缩放、左右位移、上下位移、旋转角度、亮度、对比度。
三、用什么做的
技术栈出乎意料地薄——薄到有点不像“一个 AI 应用”。
(一)前端:一个 HTML 文件就是全部
整个工具就是一个 index.html,样式和脚本全部内联,没有框架、没有打包、没有构建流程。
这么选的理由很实际:这个工具的形态是“用户偶尔用一次,用完就走”。既然如此,任何安装包、任何命令行安装都是负担。一个静态文件扔在 GitHub Pages 上,手机浏览器打开就能用,跨平台的问题也自动消失了。
界面用自适应布局做了响应式:电脑上是左右两栏(左边预览、右边控制),窄屏手机上自动变成上下单列。
(二)AI:MediaPipe Tasks Vision,推理发生在浏览器里
AI 能力用的是 Google 开源的MediaPipe Tasks Vision(版本 0.10.14)。它的关键价值在于:模型推理跑在浏览器本地,通过 WebAssembly 执行,优先走 GPU、失败则自动回退 CPU。
这一条直接解决了前面提到的隐私痛点——照片从头到尾没有离开过用户的浏览器,没有上传接口,自然也没有“服务器存了多久”的问题。
(三)两个模型的分工
AI 部分由两个模型各司其职:
模型 | 文件与体积 | 职责 |
FaceLandmarker | face_landmarker.task 约 3.6 MB | 定位 478 个面部关键点与人脸框,用来计算倾斜角度并自动摆正,同时确定裁切时人脸的位置 |
SelfieSegmenter | selfie_segmenter.tflite 约 0.25 MB | 逐像素判断“这是人还是背景”,输出置信度遮罩,即每个像素属于人体的概率,而不是非黑即白的硬判断 |
第二个模型是换底色能不能做得好看的关键。如果只用 0 和 1 的硬遮罩,头发丝和肩膀边缘会有一圈生硬的锯齿;改用 0~1 的置信度遮罩当透明度,再叠一层约 1.5px 的羽化,人像和底色之间的过渡就自然多了。
顺带说,角度纠正是先拿到双眼乃至整张脸的关键点坐标,算出倾斜角,再反向旋转把人摆正——摆正之后再重新检测一次人脸框,这样后续裁切的构图才是准的。
四、踩到的三个坑
代码是 AI 帮我写的,但坑是一个都没少踩。这三段最值得记下来。
(一)官方模型链接 404 了
一开始调的是 MediaPipe 的人脸检测模型,模型地址直接抄的官方文档。结果请求返回 404——这个模型在官方源上已经下架了。
更麻烦的是它的连锁反应:人脸模型创建失败会抛出异常,把整个模型加载流程中断,导致后面的抠图模型也没机会初始化。表现出来就是“点底色完全没反应”。
修复分两步:换成仍在维护的 FaceLandmarker(顺便拿到了更精细的关键点),并且把两个模型的加载拆开成相互独立——抠图模型成不成功以它自己为准,人脸模型挂了最多是降级成手动旋转,不至于让整页瘫痪。
(二)模型加载不出来
解决了 404,还有个更隐蔽的问题:模型和 WASM 运行时原本都挂在国外的 CDN 上。在 GitHub Pages 的国内访问环境下,这些请求经常超时,结果还是“点底色没反应”。
这里的教训是:光把模型镜像到自己的仓库还不够。MediaPipe 的组成其实是三块,缺一不可——JS 库本体(vision_bundle.mjs,约 130 KB)、WebAssembly 运行时(vision_wasm_internal.wasm 等,合计约 18 MB)、以及两个模型文件。
模型本地化了、WASM 本地化了,但 JS 库还在外部 CDN 时,引擎照样起不来——等于车有了油却没有发动机。
现在这三块全部镜像进仓库,同源托管在 github.io 上,零外部依赖,国内访问稳定加载。
(三)GitHub Pages 构建失败
把 3.6 MB 的模型文件直接提交上去之后,模型目录在线上一直是 404——但通过 GitHub API 查询,文件确确实实躺在仓库里。
查 Pages 的构建记录才看到:构建报错失败了。原因是发布源启用了 Jekyll,而它处理这种体积的二进制文件时会出问题。两步修掉:
1. 仓库根目录加一个空的 .nojekyll文件,告诉 Pages 跳过 Jekyll,静态资源原样发布。
2. 部署脚本改用 Git Data API 的 blob 通道(可以提交超过 1 MB 的单文件),并把一次要发布的多个文件合并成一次原子提交,避免连续提交把 Pages 的构建队列搞乱。
五、现在能做到什么,边界又在哪里
说效果:
●尺寸和排版是确定的——所有输出都按 300dpi 计算,像素数是固定的,不会出现“导出来发现不够清晰”的情况。
●换底色是软件级的干净——基于人体概率遮罩合成,不是用魔棒或容差去猜的。
●隐私是结构性保证的——没有上传这一步,不是“我们承诺不上传”,而是压根没有那个接口。
也说边界,这一点得诚实:
SelfieSegmenter 是一个面向人像与自拍优化的模型,它对头肩构图的照片效果最好——而证件照基本就是这个构图,所以够用。如果拿一张全身照去处理,抠图结果会偏向保留上半身,这是模型的适用边界,不是缺陷。
另一个前提是首次打开需要联网:页面的逻辑、AI 引擎、模型文件要从网上取一次(之后浏览器会缓存)。这是“纯前端方案”的天然代价,换来的是不需要服务器、不需要注册、没有运营成本。
六、写在最后
回头看,这个工具最值得说的可能不是它能做什么,而是它的成本结构:
●一个 HTML 文件,一份静态托管,零服务器、零后端、零运维。
●AI 推理全部发生在用户设备上,所以用户量增长不会带来任何算力开销。
●用户拿到的是一张干净的高清照片,不需要注册、不需要付费、也看不到水印。
这大概是现在做小工具最好的一点了:一个明确的小需求,加上浏览器里跑得动的模型,就够支撑一个真正能用的产品。
如果你也有“偶尔要一张证件照,但不想折腾”的时刻,直接扫码或点开链接就行。

扫码打开「证件照制作」
访问地址:
https://peterinblue.github.io/demo/01/
如果这个小工具帮到了你,欢迎转发给同样被证件照折腾过的朋友。