为什么你的护照照片总是被拒绝(问题出在文件,而不是图片)

发布: (2026年5月4日 GMT+8 12:49)
8 分钟阅读
原文: Dev.to

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 中轻松完成。

0 浏览
Back to Blog

相关文章

阅读更多 »

使用 AI 的开发者的四种认知原型

最近我一直在思考一件事:对大多数开发者来说,问题不再是“你在使用 AI 吗?”,而是“你是如何以及为何使用 AI?” 我的工作流...