OCR 与图像

OCR 上传入口怎么避免一张图片吃掉整机内存

上传文件只有几兆,解码后却可能需要远超预期的内存。高度可压缩的图片尤其容易让文件大小判断失效。OCR 入口需要同时限制上传字节与像素规模,还要有执行层内存、时间和并发预算。

阅读文本 / Reading text
本文使用合成样本演示处理方法。代码已通过隔离环境中的示例检查;这不代表对所有真实文件或产品效果的保证。处理重要文件前,请保留原件,并按文中的边界与验收项复核。 上传文件只有几兆,解码后却可能需要远超预期的内存。高度可压缩的图片尤其容易让文件大小判断失效。OCR 入口需要同时限制上传字节与像素规模,还要有执行层内存、时间和并发预算。 不要为了消除警告关闭保护 Pillow 对潜在解压炸弹有像素数量保护机制。直接把 MAX_IMAGE_PIXELS 设为 None 虽然能让警告消失,却也移除了重要防线。应依据业务定义预算,并明确哪些警告要被提升为拒绝。 一个保留库保护的入口检查 from io import BytesIO import warnings from PIL import Image def inspect(raw, max_bytes=4096, max_pixels=1000): if len(raw) > max_bytes: raise ValueError("upload byte budget") with warnings.catch_warnings(): warnings.simplefilter("error", Image.DecompressionBombWarning) with Image.open(BytesIO(raw)) as im: if im.width * im.height > max_pixels: raise ValueError("pixel budget") im.load() return im.size stream = BytesIO() Image.new("RGB", (40, 30), "white").save(stream, format="PNG") raw = stream.getvalue() assert len(raw) < 4096 assert inspect(raw, max_pixels=1200) == (40, 30) try: inspect(raw, max_pixels=1000) except ValueError as exc: assert "pixel" in str(exc) else: raise AssertionError("pixel budget not enforced") 预算值仅服务于合成测试。示例处理单帧,并不覆盖多帧总量、编码器漏洞或并发解码峰值。正式入口还需要帧数与累计像素限制,在隔离执行环境中处理不受信任文件。 拒绝与隔离的职责不同 控制 主要限制 仍需补充 上传字节上限 网络与存储负担 解码规模 单页像素上限 常见大图风险 多帧累计规模 内存与时间限制 实际执行消耗 可解释的错误反馈 并发上限 总资源占用 队列与背压 预算超限不是坏文件的同义词 合法的大幅工程图也可能超出默认预算,应允许走明确的大文件流程,而不是悄悄关闭所有保护。给用户说明超限的是像素还是字节,他们才知道应该裁分页面、降低采集分辨率还是选择专门处理方式。 翻译入口应把输入风险提前说明 在 OmniDoc(产品入口) 集成前增加自有输入预检,可以让不支持的大图更早得到反馈。预检不能代替平台自身限制,也不应伪称平台已经实现本文策略;它是你在上传与交付之间建立的一层可解释保障。 参考: Pillow Image 的解压保护说明 。 - 1 -
更新于 2026-10-08