Umi-OCR HTTP 二维码接口实战:Base64 识别与文本生成图片的完整调用指南
【免费下载链接】Umi-OCROCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。内置多国语言库。项目地址: https://gitcode.com/GitHub_Trending/um/Umi-OCR
本文基于 Umi-OCR 仓库中 docs/http/api_qrcode.md 的官方接口说明,系统讲解 Umi-OCR 二维码 HTTP 接口的两类能力:将 Base64 图片解析为二维码/条形码文本,以及从文本反向生成二维码图片。读完后,你可以直接在自己的项目(前端脚本、后端服务或自动化流水线)中集成离线二维码识别与生成能力,并从源码层面理解接口背后的 zxingcpp 解析链、图像预处理参数和错误码设计。
一、前置准备:启动 HTTP 服务
Umi-OCR 的二维码接口属于其 HTTP 接口体系的一部分。调用接口前需要满足以下条件:
- 开启 HTTP 服务:在 Umi-OCR 的全局设置页中勾选“高级”选项后,可以看到 HTTP 服务设置,默认处于开启状态。接口手册见 docs/http/README.md。
- 确认监听端口:默认端口为
1224,可从 UmiOCR-data/py_src/utils/pre_configs.py 中确认默认配置"server_port": 1224。若端口被占用,UmiOCR-data/py_src/server/web_server.py 中的服务逻辑会自动递增端口并记录实际端口,以启动日志中的Listening on http://...为准。 - 访问地址:本机调用使用
http://127.0.0.1:1224;如需被局域网访问,需将主机切换为“任何可用地址”。
从源码结构看,HTTP 服务基于 Bottle 框架构建,并在 UmiOCR-data/py_src/server/web_server.py 中为所有响应添加了Access-Control-Allow-Origin: *等跨域头,因此浏览器前端可以直接fetch调用;同时单次请求体上限被设置为 100 MB(BaseRequest.MEMFILE_MAX),大尺寸图片的 Base64 请求无需担心被截断。
官方手册还给出了三条运行注意事项(见 docs/http/README.md):
- 关闭 Umi-OCR 时若仍有未断开的 HTTP 连接,可能导致进程关闭不完全,需等待连接释放或强制结束进程;
- 后端组件对并发支持较差,尽量不要并发调用;
- 长时间、大批量、连续调用时小概率出现
ECONNREFUSED之类报错,重新发起请求即可。
二、接口总览:一个 URL,两种模式
二维码识别与二维码生成共用同一个 URL/api/qrcode(例:http://127.0.0.1:1224/api/qrcode),均为POST方法、JSON 字典参数。区分两种模式的关键在于请求体中携带的键:
- 请求体含
base64键 → 走图片识别二维码分支; - 请求体含
text键 → 走文本生成二维码图片分支。
这一路由分派逻辑可以直接在 UmiOCR-data/py_src/server/qrcode_server.py 中确认:
# 路由函数 def init(UmiWeb): @UmiWeb.route("/api/qrcode", method="POST") def _qrcode(): try: data = request.json except Exception as e: return json.dumps({"code": 800, "data": f"请求无法解析为json。"}) if not data: return json.dumps({"code": 801, "data": f"请求为空。"}) if "base64" in data: return json.dumps(base2text(data)) elif "text" in data: return json.dumps(text2base(data)) return json.dumps({"code": 802, "data": '指令中不存在 "base64" 或 "text"'})由此得到一组“请求级”错误码,在任何分支之前就会返回:
| code | 含义 |
|---|---|
800 | 请求体无法解析为 JSON |
801 | 请求体为空 |
802 | 指令中既没有"base64"也没有"text" |
以下分两节详细讲解两种模式的请求/响应格式与调用示例。
三、模式一:Base64 识别二维码(/api/qrcode)
传入图片的 Base64 编码字符串,返回图中所有二维码/条形码的文本、格式、位置和方向。一张图片中可能包含多个码,接口会逐一返回。
3.1 请求格式
方法:POST,参数为 JSON 字典:
- base64:必填。待识别图像的 Base64 编码字符串,无需
data:image/png;base64,等前缀。 - options:可选。参数字典,支持以下图像预处理选项:
| 参数 | 取值范围 | 默认行为 | 说明 |
|---|---|---|---|
preprocessing.median_filter_size | 1~9 的奇数 | 不滤波 | 中值滤波器大小,用于去噪 |
preprocessing.sharpness_factor | 0.1~10.0 | 不调整 | 锐度增强因子 |
preprocessing.contrast_factor | 0.1~10.0 | 不调整 | 对比度增强因子:>1 增强,0~1 减弱,1 保持原样 |
preprocessing.grayscale | true/false | false | 是否转换为灰度图 |
preprocessing.threshold | 0~255 整数 | 不生效 | 二值化阈值,仅当grayscale=true时生效 |
参数示例:
{ "base64": "iVBORw0KGgoAAAAN……", "options": { "preprocessing.sharpness_factor": 1.0, "preprocessing.contrast_factor": 1.0, "preprocessing.grayscale": false, "preprocessing.threshold": false } }3.2 响应格式
返回 JSON,顶层结构与 OCR 结果非常相似:
| 字段 | 类型 | 描述 |
|---|---|---|
code | int | 任务状态码。100为成功,101为图中无码(无文本),其余为失败 |
data | list/string | 识别结果。成功时为列表;101或失败时为错误原因字符串 |
time | double | 识别耗时(秒) |
timestamp | double | 任务开始时间戳(秒) |
code==100时,data为列表,记录图片中每个码的结果,每项包含:
| 参数名 | 类型 | 描述 |
|---|---|---|
text | string | 码的文本内容 |
format | string | 码的格式,如"QRCode",可选值见下 |
box | list | 文本框顺时针四个角的 xy 坐标:[左上,右上,右下,左下] |
orientation | int | 码的方向,0 为正上 |
score | int | 为与 OCR 格式兼容而设,永远为 1,无实际含义 |
支持的码格式format取值:
"Aztec"、"Codabar"、"Code128"、"Code39"、"Code93"、"DataBar"、"DataBarExpanded"、"DataMatrix"、"EAN13"、"EAN8"、"ITF"、"LinearCodes"、"MatrixCodes"、"MaxiCode"、"MicroQRCode"、"PDF417"、"QRCode"、"UPCA"、"UPCE"
识别成功的结果示例:
{ "code": 100, "data": [ { "orientation": 0, "box": [[4,4],[25,4],[25,25],[4,25]], "score": 1, "format": "QRCode", "text": "abc" } ], "time": 0, "timestamp": 1711521012.625574 }识别失败(含code==101无码、其他错误码)时,data为字符串错误原因,例如:
{"code": 204, "data": "【Error】zxingcpp 二维码解析失败。\n[Error] zxingcpp read_barcodes failed。……"}3.3 调用示例(JavaScript)
以下示例摘自官方文档,可直接用于浏览器或 Node 环境:
const url = "http://127.0.0.1:1224/api/qrcode"; const base64 = "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/...(此处为完整 Base64,原文见 docs/http/api_qrcode.md)"; const data = { "base64": base64 }; fetch(url, { method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify(data) }) .then(response => response.json()) .then(data => { if(data.code === 100) { console.log("QRCode count:", data.data.length); for (let d of data.data) { console.log(" text: ", d.text); console.log(" format: ", d.format); console.log(" orientation: ", d.orientation); console.log(" ===="); } } else { console.log("Error! Code", data.code, " Msg: ", data.data); } }) .catch(error => console.error(error));3.4 源码解析:识别链路与错误码
识别二维码的实际执行逻辑位于 UmiOCR-data/py_src/mission/mission_qrcode.py。HTTP 层base2text取出base64与options后,通过MissionQRCode.addMissionWait(opt, [{"base64": base64}])提交任务并同步等待结果,核心处理在msnTask方法中,链路为:读图 → 预处理 → zxingcpp 解析 → 结果转字典,各环节都有独立错误码:
| code | 阶段 | 说明 |
|---|---|---|
901 | 依赖检查 | 无法导入二维码解析器 zxingcpp |
202 | 读图 | 图片读取失败(Base64 解码或Image.open失败) |
203 | 预处理 | 图像预处理失败 |
204 | 解析 | zxingcpp.read_barcodes抛异常 |
205 | 结果转换 | 解析结果转字典失败 |
101 | 无码 | 图中未找到任何码,data为"QR code not found in the image." |
102 | 解码失败 | 检测到码但全部解码无效 |
几个值得注意的实现细节(均见 UmiOCR-data/py_src/mission/mission_qrcode.py):
- box 坐标顺序:
_zxingcpp2dict按top_left → top_right → bottom_right → bottom_left组装四个角,与文档“顺时针四角”的描述一致。 - 非文本内容的处理:当码的
content_type不是Text时(如 GS1、二进制内容),源码会先尝试按 UTF-8 解码bytes;解码失败则在文本前加[Base64]标记并以 Base64 字符串输出。也就是说text字段在极少数情况下可能是“type: Binary+ Base64”的混合内容,调用方需留意。 - 预处理参数与文档的对应关系:
_preprocessing方法(mission_qrcode.py)中,中值滤波使用 PIL 的MedianFilter(size=s)且要求奇数;锐度、对比度使用ImageEnhance;二值化逻辑为灰度值 > threshold → 255,否则 → 0,且仅在grayscale=true时执行——这解释了为什么文档强调threshold只在灰度模式下生效。 - score 恒为 1:源码中
d["score"] = 1有注释“置信度,兼容OCR格式,无意义”,与文档描述吻合。
四、模式二:从文本生成二维码图片(/api/qrcode)
传入文本,根据文本生成二维码图片,返回图片的 Base64 字符串(JPEG 编码)。URL 与识别接口一致,仅请求参数不同。
4.1 请求格式
方法:POST,参数为 JSON 字典:
- text:必填。要写入二维码的文本。
- options:可选。参数字典:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
format | string | "QRCode" | 码格式,可选值同识别接口的 format 列表 |
w | int | 0 | 生成图像宽度,0表示自动设为最小宽度 |
h | int | 0 | 生成图像高度,0表示自动设为最小高度 |
quiet_zone | int | -1 | 码四周空白边缘宽度,-1表示自动调节 |
ec_level | int | -1 | 纠错等级。-1:自动,1:7%,0:15%,3:25%,2:30%。仅对Aztec、PDF417、QRCode生效 |
参数示例:
{ "text": "要写入二维码的文本", "options": { "format": "QRCode", "w": 0, "h": 0, "quiet_zone": -1, "ec_level": -1 } }4.2 响应格式
| 字段 | 类型 | 描述 |
|---|---|---|
code | int | 100成功,其余为失败 |
data | string | 成功时为图片的 Base64 字符串(JPEG 编码);失败时为错误信息字符串 |
4.3 调用示例(JavaScript)
const url = "http://127.0.0.1:1224/api/qrcode"; const data = { "text": "test abc 123 !!!", // "options": { // "format": "QRCode", // "w": 0, // "h": 0, // "quiet_zone": -1, // "ec_level": -1, // } }; fetch(url, { method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify(data) }) .then(response => response.json()) .then(data => { if(data.code === 100) { console.log("Image base64: \n", data.data); } else { console.log("Error! Code", data.code, " Msg: ", data.data); } }) .catch(error => console.error(error));拿到 Base64 后,前端可直接拼成<img src="data:image/jpeg;base64,...">展示,后端则可解码写盘。
4.4 源码解析:生成链路
生成分支的服务端实现为 UmiOCR-data/py_src/server/qrcode_server.py 中的text2base:它从options中取出format(默认QRCode)、w/h(默认0)、quiet_zone(默认-1)、ec_level(默认-1),调用MissionQRCode.createImage得到 PIL 图像,再以JPEG格式写入BytesIO并 Base64 编码返回——这与文档“返回图片编码为 jpeg”的描述一致;异常时返回{"code": 200, "data": "[Error] ..."}。
真正的编码动作在 UmiOCR-data/py_src/mission/mission_qrcode.py 的createImage中:
- 先通过
getattr(zxingcpp.BarcodeFormat, format, None)校验格式名是否合法,非法格式直接返回[Error] format {format} not in zxingcpp.BarcodeFormat!; - 调用
zxingcpp.write_barcode(bFormat, text, w, h, quiet_zone, ec_level)生成位图,再经Image.fromarray(bit, "L")转为灰度 PIL 图像; - 源码注释明确了纠错等级映射:
-1自动、1对应 L(7%)、0对应 M(15%)、3对应 Q(25%)、2对应 H(30%),且纠错等级仅用于Aztec、PDF417和QRCode——与文档表格一致。
五、错误码速查与常见问题
把请求级与分支级错误码汇总如下,方便排障:
| code | 所属分支 | 含义 |
|---|---|---|
800 | 路由层 | 请求无法解析为 JSON |
801 | 路由层 | 请求为空 |
802 | 路由层 | 指令中不存在"base64"或"text" |
901 | 识别 | zxingcpp 解析器导入失败 |
100 | 识别/生成 | 成功 |
101 | 识别 | 图中无码 |
102 | 识别 | 码全部解码失败 |
200 | 生成 | 生成过程抛异常(data为错误信息) |
202 | 识别 | 图片读取失败 |
203 | 识别 | 图像预处理失败 |
204 | 识别 | zxingcpp 解析异常 |
205 | 识别 | 结果转字典失败 |
实践建议:
- 先验连通性:浏览器访问
http://127.0.0.1:1224/应返回 Umi-OCR 的名称标识(见 web_server.py 的根路由),可用于确认服务已启动。 - 小图失败时加预处理:对模糊、有噪点的截图,可组合
median_filter_size(奇数)+contrast_factor(>1)+ 灰度/二值化重试,参数含义见 3.1 节表格。 - 避免并发:官方手册明确后端并发支持较差,批量业务请串行调用;偶发
ECONNREFUSED时重试即可。 - 注意
score字段:该字段仅用于格式兼容,不要将其当作置信度使用。
六、相关文档与延伸阅读
二维码接口并非孤立存在,Umi-OCR 的 HTTP 接口手册中还包含可组合使用的其他能力:
- HTTP接口手册总览:服务开启、局域网访问与注意事项;
- 图片OCR接口:Base64 图片文字识别,其响应格式(box/score/end)与二维码接口刻意保持兼容;
- 文档识别(PDF)流程:上传 → 轮询 → 下载 → 清理的完整任务流,配套 Python 示例 与 Web 示例;
- 命令行接口:
/argv接口等价于命令行传参,仅允许127.0.0.1调用,可参考 README_CLI.md 了解全部命令行参数; - CHANGE_LOG.md 记录了二维码功能演进:二维码解析库改用 zxingcpp、新增二维码识别页与生成功能、HTTP 二维码接口支持图像预处理参数等,可作为版本能力确认依据。
【免费下载链接】Umi-OCROCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。内置多国语言库。项目地址: https://gitcode.com/GitHub_Trending/um/Umi-OCR
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考