qwen/image-ocr

基于通义千问大模型的图片文字识别与JSON结构化输出库

Maintainers

Package info

github.com/zeng444/aliocr

pkg:composer/qwen/image-ocr

Statistics

Installs: 7

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.0.2 2026-05-08 08:17 UTC

This package is not auto-updated.

Last update: 2026-05-08 08:19:28 UTC


README

基于通义千问视觉大模型(qwen-vl-ocr)的图片文字识别与 JSON 结构化输出 PHP 库。

通过调用阿里云 DashScope API,将图片中的文字内容智能识别并自动解析为结构化 JSON 数据。内置 9 种中国常见证件/票据类型的专用识别模板,开箱即用。

特性

  • 基于 PHP 7.2+,使用 Guzzle HTTP 客户端
  • 调用通义千问视觉模型(qwen-vl-ocr)识别图片中的文字
  • 自动解析模型返回的 JSON 结构化数据(支持纯 JSON 和 Markdown 代码块格式)
  • 内置 9 种证件/票据类型专用 Prompt 模板,精准提取字段
  • 支持自定义 Prompt 指令和 PromptBuilder 替换
  • 完善的异常处理(区分 API 请求异常和 JSON 解析异常)
  • 支持 URL 和 Base64 两种图片输入方式

支持的证件类型

类型 类名 标识符 说明
身份证正面 FrontIdCard frontIdCard 姓名、性别、民族、出生日期、住址、身份证号
身份证背面 BackIdCard backIdCard 签发机关、有效期限
营业执照 BusinessLicense businessLicense 统一社会信用代码、企业名称、法人、经营范围等 14 个字段
车辆合格证 Certificate certificate 合格证编号、车架号、发动机号等 38 个字段
发票 CarInvoice carInvoice 发票代码、金额、购销双方信息、明细行等 27 个字段
行驶证正页 FrontLicense frontLicense 号牌号码、车辆类型、所有人、VIN 等 11 个字段
行驶证副页 BackLicense backLicense 核定载人数、总质量、外廓尺寸等 12 个字段
驾驶证正面 FrontDrivingLicense frontDrivingLicense 证号、姓名、准驾类型、有效期限等 11 个字段
驾驶证背面 BackDrivingLicense backDrivingLicense 姓名、档案编号、记录、证号

安装

composer require qwen/image-ocr

阿里云 Qwen 模型计费价格

模型 类型 输入价格 输出价格
qwen-vl-ocr 视觉识别 · OCR 专项 ¥0.3 / 百万 token ¥0.5 / 百万 token
qwen-vl-plus-latest 视觉理解 · 多模态增强 ¥0.8 / 百万 token ¥2.0 / 百万 token

计费单位:元(CNY)/ 每百万 token

仅需 OCR 文字识别,降低成本,默认使用 qwen-vl-ocr 模型;存在手写识别可切换为 qwen-vl-plus-latest

$client = new Client('sk-xxxxxxxx', [
    'model' => 'qwen-vl-plus-latest',
]);

快速开始

1. 通用文字识别

使用默认 Prompt,识别图片中所有文字并输出结构化 JSON:

<?php
require 'vendor/autoload.php';

use Qwen\ImageOcr\Client;

$client = new Client('sk-xxxxxxxx');

$result = $client->recognize('https://example.com/image.jpg');

print_r($result->getData());
echo $result->toJson();

2. 自定义 Prompt 识别

传入自定义指令,控制模型的输出格式:

$instruction = '请识别图片中的所有文字,并按表格形式输出为 JSON';
$result = $client->recognizeWithPrompt('https://example.com/table.jpg', $instruction);
echo $result->toJson();

3. 按证件类型识别(推荐)

使用内置的证件类型模板,精准提取特定字段:

use Qwen\ImageOcr\OcrType\FrontIdCard;
use Qwen\ImageOcr\OcrType\BusinessLicense;

// 身份证正面
$result = $client->recognizeAs('https://example.com/id-front.jpg', new FrontIdCard());
echo $result->get('idNumber'); // 18位身份证号码

// 营业执照
$result = $client->recognizeAs('https://example.com/license.jpg', new BusinessLicense());
echo $result->get('companyName'); // 企业名称

4. 使用 Base64 图片

支持 base64 data URI 格式的图片输入:

$base64Image = 'data:image/jpeg;base64,/9j/4AAQSkZJRg...';
$result = $client->recognize($base64Image);

证件类型识别示例

以下示例展示了所有 9 种证件类型的调用方式:

<?php
require 'vendor/autoload.php';

use Qwen\ImageOcr\Client;
use Qwen\ImageOcr\OcrType\BusinessLicense;
use Qwen\ImageOcr\OcrType\Certificate;
use Qwen\ImageOcr\OcrType\FrontIdCard;
use Qwen\ImageOcr\OcrType\BackIdCard;
use Qwen\ImageOcr\OcrType\CarInvoice;
use Qwen\ImageOcr\OcrType\FrontLicense;
use Qwen\ImageOcr\OcrType\BackLicense;
use Qwen\ImageOcr\OcrType\FrontDrivingLicense;
use Qwen\ImageOcr\OcrType\BackDrivingLicense;
use Qwen\ImageOcr\Exception\ApiException;
use Qwen\ImageOcr\Exception\OcrException;

$client = new Client('sk-xxxxxxxx');

// 营业执照
$result = $client->recognizeAs('https://example.com/business-license.jpg', new BusinessLicense());
// 输出字段:creditCode, companyName, companyType, businessAddress, legalPerson,
//           businessScope, registeredCapital, RegistrationDate, validPeriod,
//           validFromDate, validToDate, companyForm, issueDate, title

// 车辆合格证
$result = $client->recognizeAs('https://example.com/certificate.jpg', new Certificate());
// 输出字段:certificateNumber, vinCode, vehicleModel, vehicleName, vehicleBrand,
//           manufactureName, engineModel, engineNumber, fuelType, displacement 等 38 个字段

// 身份证正面
$result = $client->recognizeAs('https://example.com/id-front.jpg', new FrontIdCard());
// 输出字段:name, sex, ethnicity, birthDate, address, idNumber

// 身份证背面
$result = $client->recognizeAs('https://example.com/id-back.jpg', new BackIdCard());
// 输出字段:issueAuthority, validPeriod

// 发票
$result = $client->recognizeAs('https://example.com/invoice.jpg', new CarInvoice());
// 输出字段:invoiceCode, invoiceNumber, invoiceDate, purchaserName, sellerName,
//           totalAmount, invoiceDetails[] 等 27 个字段

// 行驶证正页
$result = $client->recognizeAs('https://example.com/vehicle-front.jpg', new FrontLicense());
// 输出字段:licensePlateNumber, vehicleType, owner, model, vinCode, engineNumber 等

// 行驶证副页
$result = $client->recognizeAs('https://example.com/vehicle-back.jpg', new BackLicense());
// 输出字段:licensePlateNumber, passengerCapacity, totalWeight, curbWeight 等

// 驾驶证正面
$result = $client->recognizeAs('https://example.com/driving-front.jpg', new FrontDrivingLicense());
// 输出字段:licenseNumber, name, sex, approvedType, validFromDate, validPeriod 等

// 驾驶证背面
$result = $client->recognizeAs('https://example.com/driving-back.jpg', new BackDrivingLicense());
// 输出字段:name, recordNumber, record, licenseNumber

API 文档

Client

客户端核心类,提供三种识别方法。

__construct($apiKeyOrConfig, array $options = [])

创建客户端实例。

参数:

  • $apiKeyOrConfig:API Key 字符串或 Config 实例
  • $options:可选配置数组
    • base_url:API 端点(默认:https://dashscope.aliyuncs.com/compatible-mode/v1
    • model:模型名称(默认:qwen-vl-ocr
    • timeout:请求超时秒数(默认:60)
    • temperature:采样温度 [0, 2](默认:0,确定性输出)
    • top_p:核采样阈值 (0, 1],与 temperature 二选一
    • top_k:候选 Token 数量(默认:20)
    • enable_thinking:是否开启混合思考模式(默认:false)
// 使用 API Key 字符串
$client = new Client('sk-xxxxxxxx');

// 自定义配置
$client = new Client('sk-xxxxxxxx', [
    'timeout' => 120,
    'model'   => 'qwen-vl-max',
]);

// 使用 Config 对象
$config = new Config('sk-xxxxxxxx', [
    'base_url' => 'https://custom-endpoint.com/v1',
    'model'    => 'qwen-vl-max',
    'timeout'  => 90,
]);
$client = new Client($config);

recognize(string $imageUrl): OcrResult

通用文字识别,使用默认 Prompt 提取图片中所有文字并结构化输出。

参数: $imageUrl — 图片 URL 或 base64 data URI

recognizeWithPrompt(string $imageUrl, string $instruction): OcrResult

使用自定义 Prompt 识别图片。

参数:

  • $imageUrl — 图片 URL 或 base64 data URI
  • $instruction — 自定义指令文本

recognizeAs(string $imageUrl, OcrTypeInterface $type): OcrResult

按业务类型识别图片,使用证件类型专属的 system/user Prompt。

参数:

  • $imageUrl — 图片 URL 或 base64 data URI
  • $type — 证件类型对象(实现 OcrTypeInterface 接口)

setPromptBuilder(PromptBuilder $builder): self

替换默认 PromptBuilder,用于高级定制。

setHttpClient(HttpClient $client): self

替换默认 Guzzle HttpClient,用于测试或代理场景。

OcrResult

识别结果封装类。

方法 返回类型 说明
getData() array 获取解析后的结构化数组
getRawText() string 获取模型返回的原始文本(可能包含 Markdown 代码块)
getRawResponse() array 获取完整的 API 响应数组
toJson(int $flags) string 将结构化数据序列化为 JSON 字符串
get(string $key, $default) mixed 快捷访问结构化数据中的某个键
$result = $client->recognizeAs($url, new FrontIdCard());

$result->get('idNumber');           // "110101199001011234"
$result->get('name');               // "张三"
$result->get('notExist', '默认值');  // "默认值"
$result->getData();                 // 完整数组
$result->toJson();                  // JSON 字符串
$result->getRawText();              // 模型原始输出
$result->getRawResponse();          // API 完整响应

OcrTypeInterface

证件类型接口,所有证件类型对象必须实现。

方法 说明
getSystemPrompt() 返回系统提示词(role: system 消息内容)
getUserPrompt() 返回用户提示词(包含字段提取指令和 JSON 格式要求)
getTypeName() 返回证件类型标识符(camelCase)

自定义证件类型

实现 OcrTypeInterface 接口或继承 AbstractOcrType 抽象类,即可创建自定义证件类型:

use Qwen\ImageOcr\OcrType\AbstractOcrType;

class BankCard extends AbstractOcrType
{
    public function getTypeName(): string
    {
        return 'bankCard';
    }

    public function getUserPrompt(): string
    {
        return <<<'PROMPT'
请识别银行卡图片中的信息,以 JSON 格式输出以下字段:

{
  "bankName": "银行名称",
  "cardNumber": "银行卡号",
  "cardType": "卡类型(借记卡/信用卡)",
  "holderName": "持卡人姓名"
}

只输出 JSON,不要包含任何额外说明。如某字段无法识别,对应值设为空字符串。
PROMPT;
    }
}

// 使用自定义类型
$result = $client->recognizeAs('https://example.com/bank-card.jpg', new BankCard());
echo $result->get('cardNumber');

异常处理

use Qwen\ImageOcr\Exception\ApiException;
use Qwen\ImageOcr\Exception\OcrException;

try {
    $result = $client->recognizeAs($imageUrl, new FrontIdCard());
} catch (ApiException $e) {
    // API 请求失败(网络错误、认证失败、模型返回错误等)
    echo "API 错误:" . $e->getMessage();
    echo "状态码:" . $e->getStatusCode();
    echo "响应体:" . $e->getResponseBody();
} catch (OcrException $e) {
    // JSON 解析失败或其他业务错误
    echo "OCR 错误:" . $e->getMessage();
}

高级用法

自定义 PromptBuilder

use Qwen\ImageOcr\Prompt\PromptBuilder;

$builder = new PromptBuilder('请识别图片中的发票信息,输出为 JSON');
$client->setPromptBuilder($builder);

$result = $client->recognize($imageUrl);

使用 Config 对象

use Qwen\ImageOcr\Config;
use Qwen\ImageOcr\Client;

$config = new Config('sk-xxxxxxxx', [
    'base_url'       => 'https://dashscope.aliyuncs.com/compatible-mode/v1',
    'model'          => 'qwen-vl-ocr',
    'timeout'        => 90,
    'temperature'    => 0,
    'top_k'          => 20,
    'enable_thinking' => false,
]);

$client = new Client($config);

Docker 运行

项目提供了 docker-compose.yml,可快速搭建运行环境:

# 启动容器
docker-compose up -d

# 在容器中运行示例脚本
docker exec ocr php /data/examples/probe_types.php

# 运行单元测试
docker exec ocr vendor/bin/phpunit

# 运行集成测试(需设置环境变量)
docker exec -e RUN_INTEGRATION_TESTS=1 -e QWEN_API_KEY=sk-xxxxxxxx ocr vendor/bin/phpunit --testsuite Integration

项目结构

aliocr/
├── src/
│   ├── Client.php                    # 核心客户端,提供三种识别方法
│   ├── Config.php                    # 配置管理(API Key、模型、超时等)
│   ├── OcrResult.php                 # 识别结果封装
│   ├── Exception/
│   │   ├── OcrException.php          # 基础异常类
│   │   └── ApiException.php          # API 请求异常(含状态码和响应体)
│   ├── OcrType/
│   │   ├── OcrTypeInterface.php      # 证件类型接口
│   │   ├── AbstractOcrType.php       # 抽象基类(提供默认 system prompt)
│   │   ├── FrontIdCard.php           # 身份证正面
│   │   ├── BackIdCard.php            # 身份证背面
│   │   ├── BusinessLicense.php       # 营业执照
│   │   ├── Certificate.php           # 车辆合格证
│   │   ├── CarInvoice.php            # 发票
│   │   ├── FrontLicense.php          # 行驶证正页
│   │   ├── BackLicense.php           # 行驶证副页
│   │   ├── FrontDrivingLicense.php   # 驾驶证正面
│   │   └── BackDrivingLicense.php    # 驾驶证背面
│   ├── Parser/
│   │   └── JsonParser.php            # JSON 解析器(支持 Markdown 代码块提取)
│   └── Prompt/
│       └── PromptBuilder.php         # Prompt 构建器
├── examples/
│   └── probe_types.php               # 证件类型探测示例脚本
├── tests/
│   ├── Integration/
│   │   └── RecognizeTest.php         # 集成测试(真实 API 调用)
│   └── Unit/
│       ├── ClientTest.php
│       ├── ConfigTest.php
│       ├── JsonParserTest.php
│       ├── OcrResultTest.php
│       └── PromptBuilderTest.php
├── composer.json
├── docker-compose.yml
├── phpunit.xml
└── README.md

系统要求

  • PHP >= 7.2
  • Guzzle HTTP 客户端 ^6.5 或 ^7.0
  • 阿里云 DashScope API Key

许可证

MIT License

相关链接