首页
/ Umi-OCR HTTP 二维码接口实战:Base64 识别与文本生成图片的完整调用指南

Umi-OCR HTTP 二维码接口实战:Base64 识别与文本生成图片的完整调用指南

2026-09-05 12:17:28作者:温玫谨Lighthearted

本文基于 Umi-OCR 仓库中 docs/http/api_qrcode.md 的官方接口说明,系统讲解 Umi-OCR 二维码 HTTP 接口的两类能力:将 Base64 图片解析为二维码/条形码文本,以及从文本反向生成二维码图片。读完后,你可以直接在自己的项目(前端脚本、后端服务或自动化流水线)中集成离线二维码识别与生成能力,并从源码层面理解接口背后的 zxingcpp 解析链、图像预处理参数和错误码设计。

一、前置准备:启动 HTTP 服务

Umi-OCR 的二维码接口属于其 HTTP 接口体系的一部分。调用接口前需要满足以下条件:

  1. 开启 HTTP 服务:在 Umi-OCR 的全局设置页中勾选“高级”选项后,可以看到 HTTP 服务设置,默认处于开启状态。接口手册见 docs/http/README.md
  2. 确认监听端口:默认端口为 1224,可从 UmiOCR-data/py_src/utils/pre_configs.py 中确认默认配置 "server_port": 1224。若端口被占用,UmiOCR-data/py_src/server/web_server.py 中的服务逻辑会自动递增端口并记录实际端口,以启动日志中的 Listening on http://... 为准。
  3. 访问地址:本机调用使用 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 取出 base64options 后,通过 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):

  1. box 坐标顺序_zxingcpp2dicttop_left → top_right → bottom_right → bottom_left 组装四个角,与文档“顺时针四角”的描述一致。
  2. 非文本内容的处理:当码的 content_type 不是 Text 时(如 GS1、二进制内容),源码会先尝试按 UTF-8 解码 bytes;解码失败则在文本前加 [Base64] 标记并以 Base64 字符串输出。也就是说 text 字段在极少数情况下可能是“type: Binary + Base64”的混合内容,调用方需留意。
  3. 预处理参数与文档的对应关系_preprocessing 方法(mission_qrcode.py)中,中值滤波使用 PIL 的 MedianFilter(size=s) 且要求奇数;锐度、对比度使用 ImageEnhance;二值化逻辑为 灰度值 > threshold → 255,否则 → 0,且仅在 grayscale=true 时执行——这解释了为什么文档强调 threshold 只在灰度模式下生效。
  4. 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%。仅对 AztecPDF417QRCode 生效

参数示例:

{
    "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.pycreateImage 中:

  • 先通过 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%),且纠错等级仅用于 AztecPDF417QRCode——与文档表格一致。

五、错误码速查与常见问题

把请求级与分支级错误码汇总如下,方便排障:

code 所属分支 含义
800 路由层 请求无法解析为 JSON
801 路由层 请求为空
802 路由层 指令中不存在 "base64""text"
901 识别 zxingcpp 解析器导入失败
100 识别/生成 成功
101 识别 图中无码
102 识别 码全部解码失败
200 生成 生成过程抛异常(data 为错误信息)
202 识别 图片读取失败
203 识别 图像预处理失败
204 识别 zxingcpp 解析异常
205 识别 结果转字典失败

实践建议:

  1. 先验连通性:浏览器访问 http://127.0.0.1:1224/ 应返回 Umi-OCR 的名称标识(见 web_server.py 的根路由),可用于确认服务已启动。
  2. 小图失败时加预处理:对模糊、有噪点的截图,可组合 median_filter_size(奇数)+ contrast_factor(>1)+ 灰度/二值化重试,参数含义见 3.1 节表格。
  3. 避免并发:官方手册明确后端并发支持较差,批量业务请串行调用;偶发 ECONNREFUSED 时重试即可。
  4. 注意 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 二维码接口支持图像预处理参数等,可作为版本能力确认依据。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
983
503
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384