为什么你的护照照片总是被拒绝(问题出在文件,而不是图片)
Source: Dev.to
如果你曾经在政府门户网站上传护照照片,却收到模糊的“照片被拒绝”错误,问题通常不在于照片本身——而是文件。
我运营 IDPhotoSnap,这是一款免费基于浏览器的护照照片工具。最常见的支持问题是一种变体:“我的照片看起来没问题,为什么门户说它有误?”
答案几乎总是出在文件的元数据,而不是可见的图像。
8 种文件级别的拒绝原因
1. 文件大小超出范围
大多数使领馆门户网站都有严格的大小限制:
- 美国国务院 DS‑160: 最大 240 KB
- 英国护照门户: 50 KB – 10 MB
- 申根签证门户: 240 KB – 6 MB(因国家而异)
- 印度护照 Seva: 20 KB – 300 KB
现代手机默认拍摄 4–8 MB 的照片,因此门户往往在任何人工查看图片之前就拒绝上传。
2. DPI 错误
DPI 存储在元数据中;它不会改变像素数据。手机相机给照片打上 72 DPI 的标签,而使领馆的打印流程要求 300 DPI。
// In a JPEG, DPI lives in the JFIF header (bytes 13‑18) or EXIF tag 0x011A.
// Changing it does NOT recompress or resize – just rewrites those bytes.
你可以使用 ImageMagick 验证 DPI:
identify -format "%x x %y\n" photo.jpg # → 72x72 (needs 300x300)
像素内容是相同的;导致验证失败的是元数据标签。
3. 尺寸错误
每个国家都有不同的尺寸要求:
| 国家 | 尺寸 |
|---|---|
| 美国 | 600 × 600 px (2 × 2 in) |
| 申根 | 35 × 45 mm |
| 英国 | 35 × 45 mm,最低 600 × 750 px |
| 印度 | 51 × 51 mm,600 × 600 px |
| 日本 | 35 × 45 mm,413 × 531 px |
一张符合某个国家要求的照片可能不符合另一个国家的要求——没有通用尺寸。
4. 格式错误(HEIC、WebP、PNG)
iPhone 默认保存为 HEIC;Android 有时保存为 WebP。大多数政府门户只接受 JPG,约有一半还会拒绝 PNG。
HEIC → JPG 的转换可以在客户端使用编译为 WASM 的 libheif 完成:
import { decode } from 'libheif-js'
async function heicToJpeg(file) {
const buf = await file.arrayBuffer()
const decoder = new Decoder()
const data = decoder.decode(new Uint8Array(buf))
// …draw onto canvas, export as JPEG with quality 0.92
}
5. 背景不是纯白
背景验证器会寻找 RGB(255,255,255) ± 一个小误差。常见的失败情况:
- 微白墙面 (255, 250, 245)
- 窗光在墙面上的渐变
- 头部后方的柔和阴影
要真正符合要求,需要彻底更换背景。浏览器内的机器学习分割模型如 MODNet(约 25 MB ONNX)可通过 onnxruntime-web 运行。
6. 压缩伪影
质量为 60% 的 JPEG 会出现明显的块状伪影。验证器有时会因低 SSIM 而标记。请以 90‑95% 的质量重新压缩;如果文件仍然过大,则降低像素尺寸——但绝不能低于尺寸阈值。
7. 色彩配置文件不匹配
iPhone 拍摄的照片可能使用 Display‑P3,而验证器期望 sRGB。导出前请转换:
ctx.imageSmoothingEnabled = true
ctx.drawImage(img, 0, 0)
const data = ctx.getImageData(0, 0, w, h)
// Canvas defaults to sRGB – drawing converts the profile
8. 嵌入式缩略图不匹配
一些门户会比较 EXIF 缩略图与主图像。如果两者不同(例如裁剪了主图但缩略图仍是原始图),文件会被标记为已编辑。请完全剥离 EXIF:
// Re‑encoding via canvas removes all EXIF/XMP/IPTC metadata
canvas.toBlob(blob => {
// upload blob …
}, 'image/jpeg', 0.95)
为什么在这里使用仅浏览器工具是合理的
上述所有操作都是纯像素处理,可以在浏览器本地完成——无需服务器计算,也不需要云端 AI。即使是背景替换,也可以在中等配置的笔记本电脑上使用 onnxruntime-web 本地运行,耗时约 2‑5 秒。
将你的面部照片上传到第三方服务去完成本可以在 WebAssembly 中良好运行的工作,是糟糕的架构设计,也更不利于隐私。
如果你想看到这种方法的实际效果,IDPhotoSnap 能够在 85+ 国家 处理所有八项问题,且无需任何上传。它的 Photo Rejected hub 能诊断被拒的照片并针对性地修复,全部在客户端完成。
Lesson
当政府门户网站拒绝“一张好看的照片”时,90 % 的情况是它在读取文件的元数据,而不是图片本身。对此的工程实现主要是要在 JPEG 头信息中有意识地写入内容——DPI 标签、尺寸、色彩配置文件、嵌入的缩略图——而不是像素本身。
FAQ
Q: 为什么护照门户不提供具体的错误信息?
A: 它们会依次运行一系列验证器(大小 → 格式 → DPI → 尺寸 → 背景),并在第一次失败时中止。有些只显示最后的错误代码;很多根本不给出有用的反馈。
Q: 打印照片能解决 DPI 吗?
A: 对于现场提交是可以的,但对在线门户不行——它们读取文件的元数据,而不是打印件。
Q: 我可以直接把 HEIC 转成 JPG 就算完成吗?
A: 对于大小和格式检查通常可以,但转换器通常会把 DPI 标签重置为 72 DPI,并保持手机默认的尺寸不变,所以你通常还需要进行一次尺寸调整和 DPI 重写。
Q: 这是否需要服务器端处理?
A: 在 99 % 的情况下不需要。唯一可能需要服务器端的是背景去除(需要大型模型文件)。其他全部可以在 Canvas 加上几 KB 的 JavaScript 中轻松完成。