You need to enable JavaScript to run this app.
导航
调用方式
最近更新时间:2024.11.07 14:22:56首次发布时间:2024.09.12 11:33:01
接口简介

支持对数字扫描版PDF、图片进行深度解析和结构化处理,通过版面分析、文字识别,按照阅读顺序提取PDF、图片中的文本、表格、公式、图片等关键信息,最终组织成半结构化的带有语义信息和逻辑结构的文档,并以Markdown、JSON格式返回,覆盖常见论文、书籍、行业报告、公司内部文件等众多文件类型,加速大语言模型训练、开发、应用;

限制条件
名称内容
文件要求1. 文件格式:pdf、图片(JPG、JPEG、PNG、BMP、PDF等常见格式,建议使用JPG格式)。
2. 文件大小:
a.如果传Base64编码,要求Base64编码和urlencode之后不超过 8 MB。
b.如果传文件完整URL, URL建议使用火山引擎对象存储,其他外部链接耗时与稳定性可能会收到影响,导致接口响应失败。
3. 输入文件过大时,返回的HttpCode如下:400/413/502。
请求说明

基本信息

名称内容
接口地址https://visual.volcengineapi.com
请求方式POST
Content-Typeapplication/x-www-form-urlencoded
是否需要鉴权

请求参数

header请求参数

以下请求参数列表仅列出了接口请求参数和必要公共参数,完整公共参数列表见 公共参数

名称类型是否必填描述
X-DateString使用UTC时间,精确到秒。请使用格式:YYYYMMDD'T'HHMMSS'Z' ,例如:20201103T104027Z

Authorization

String

HMAC-SHA256:签名方法
-Credential为签名凭证,其中:
-AccessKeyId为访问密钥ID,可在 访问密钥(Access Key) 获取;
-ShortDate为请求的短时间,使用UTC时间,精确到日。请使用格式:YYYYMMDD,例如:20180201
-Region为请求地区,国内一般为为cn-north-1
-Service为请求的服务,文字识别一般为cv
-SignedHeaders为参与签名计算的头部信息,content-typehost 为必选头部;
-Signature为签名,可在 签名方法 获取。
注:我们提供了SDK及签名示例供您实现服务快速接入,具体可参考 快速接入
例如:HMAC-SHA256 Credential={AccessKeyId}/{ShortDate}/{Region}/{Service}/request, SignedHeaders={SignedHeaders}, Signature={Signature}

X-Security-TokenString指安全令牌服务(Security Token Service,STS) 颁发的临时安全凭证中的SessionToken,使用长期密钥时无需填写该参数。

Query请求参数

参数可选/必选类型说明
Action必选String接口名,取值:OCRPdf
Version必选String版本号,取值:2021-08-23

Body参数

参数可选/必选类型说明
image_base64与image_url二选一String文件的base64编码
注意: 只需要传文件的base64值,要求Base64编码和urlencode之后不超过 8 MB
image_url与image_base64二选一String文件的URL链接
注意: 要求image_base64与image_url二选一,如果2个字段都有,优先解析image_base64。
建议使用火山引擎对象存储,其他外部链接耗时与稳定性可能会收到影响
version必选String版本号, 取值:v3
file_type可选String文件类型:"pdf"/"image", 默认为pdf
page_start可选Intpdf从第几页开始解析, 默认为0
page_num可选Intpdf解析页数, 默认为16, 最多支持100页
parse_mode可选String文本解析模式:"auto"/"ocr", 默认为"auto"。 “auto”综合文字识别和解析模式,速度更快;“ocr”仅为文字识别模式,如果在“auto”获取解析结果中有不符合原文内容乱码,则可以尝试该模式修正。
table_mode可选String表格返回格式:"html"/"markdown", 默认为"markdown"
filter_header可选String页眉、页脚、脚注过滤开关:"true"/"false", 默认为"true",关闭插入正文
输出说明

通用输出参数

请参考通用返回字段及错误码 |

业务输出参数

data 字段说明

字段类型说明备注
markdownStringmarkdown字符串整本PDF
detailArray of ResultPDF解析结构化信息见下面result说明

result 字段说明

字段类型说明备注
page_mdString每页markdown字符串
page_image_hwString图像信息
textblocksArray of Textblock段落信息见下面textblock字段说明
page_idInt当前页码当前PDF中页码

textblock 字段说明

字段类型说明备注
textString段落文本
boxArray of Float元素块坐标信息左上、右下坐标
labelString段落文本类别见下面label字段说明
norm_boxArray of Float元素块坐标信息归一化坐标
font_sizeInt字体大小仅供参考
is_boldBool是否粗体仅供参考
is_italicBool是否斜体仅供参考
urlString图片的超链接markdown中渲染用

label 字段说明

字段类型说明
titleString标题
authorString作者
secString章节标题
paraString普通段落
headerString页眉
footString页脚
fnoteString脚注
imageString图片
tableString表格
capString图/表描述

输出示例

{
    "code":10000,
    "data":{
        "markdown": "Article 2: Active region PIC experiment\n63"
        "detail": {
			    [
			        {
			            "page_id": 0,
			            "page_md": "Article 2: Active region PIC experiment\n63",
			            "page_image_hw": {
			                "h": 1200,
			                "w": 848
			            },
			            "textblocks": [
			                {
			                    "box": {
			                        "x0": 172,
			                        "y0": 175,
			                        "x1": 591,
			                        "y1": 207
			                    },
			                    "text": "Article 2: Active region PIC experiment",
			                    "label": "para",
			                    "norm_box": {
			                        "y0": 0.14583333333333334,
			                        "x1": 0.6969339622641509,
			                        "y1": 0.1725,
			                        "x0": 0.2028301886792453
			                    },
			                    "font_size": 14,
			                    "is_bold": false,
			                    "is_italic": false
			                },
			                {
			                    "text": "63",
			                    "label": "foot",
			                    "norm_box": {
			                        "x0": 0.4834905660377358,
			                        "y0": 0.88,
			                        "x1": 0.5094339622641509,
			                        "y1": 0.8958333333333334
			                    },
			                    "font_size": 9,
			                    "is_bold": false,
			                    "is_italic": false,
			                    "box": {
			                        "x0": 410,
			                        "y0": 1056,
			                        "x1": 432,
			                        "y1": 1075
			                    }
			                }
			            ]
			        }
			    ]
			    }
			}
    },
    "message":"Success",
    "request_id":"021629427766315fdbddc01010500400000000000000068da22fd",
    "time_elapsed":"5.330714543s"
}
错误码

通用错误码

请参考通用返回字段及错误码

业务错误码

HttpCode错误码错误消息描述
20010000请求成功
40150205"Image Size Exceeds Maximum Limit: please compress the image"文件大小超过上限
40050207"Image Decode Error: image format unsupported"文件解码错误,文件内容为空或格式错误
40150400"Access denied due to invalid authentication information"鉴权失败
40450402"Invalid Request URL"无效的请求路径
50050500"Internal Error: please contact with bytedance engineering team"内部错误,需要联系开发人员

附录

PDF分页

为保证解析稳定性,页数较多的建议拆页
也可通过page_start和page_num控制

import fitz # PyMuPDF==1.18.19
import os
import math 

def split_pdf(input_dir, output_dir, split_num=16):
    """
    将指定目录中的每个 PDF 文件分割成多个小 PDF 文件。

    参数:
    input_dir (str): 输入 PDF 文件所在的目录。
    output_dir (str): 输出分割后的 PDF 文件的目录。
    split_num (int): 每个小 PDF 文件包含的页数,默认为 16。
    """
    # 遍历输入目录中的所有 PDF 文件
    for pdf_name in os.listdir(input_dir):
        pdf_path = os.path.join(input_dir, pdf_name):
        pdf = fitz.open(pdf_path) 
        count = pdf.pageCount # 获取 PDF 文件的总页数
        for page_num in range(count // split_num + math.ceil((count % split_num) / split_num)):
            output_pdf = fitz.open()  # 创建一个新的 PDF 对象

            # 计算当前分割的起始页和结束页
            start_page = page_num*split_num
            end_page = min(page_num*split_num+split_num-1, count-1)
            output_pdf.insert_pdf(pdf, from_page=start_page, to_page=end_page)  # 将指定页面插入新的 PDF 对象

            out_name = os.path.join(output_dir, f"{pdf_name}_{start_page}_{end_page}.pdf") 
            output_pdf.save(out_name)  # 保存新的 PDF 文件

上传火山引擎对象存储URL

base64文件大小超过8M上传火山引擎对象存储,通过url请求
详情见对象存储SDK

import os
import tos
def upload_file_tob(pdf_path, bucket_name, object_key_prefix):
    """
    将指定的 PDF 文件上传到 TOS(对象存储服务)。

    参数:
    pdf_path (str): 要上传的 PDF 文件的本地路径。
    bucket_name (str): TOS 存储桶的名称。
    object_key_prefix (str): 对象键的前缀。

    返回:
    str: 上传文件的 URL。
    """

    ak = ""
    sk = ""
    endpoint = "tos-cn-beijing.volces.com"
    region = "cn-beijing"
    object_key = os.path.join(object_key_prefix, os.path.basename(pdf_path))
    url = f"https://{bucket_name}.{endpoint}/{object_key}"

    content = open(pdf_path, "rb").read()

    try:
        client = tos.TosClientV2(ak, sk, endpoint, region)
        result = client.put_object(bucket_name, object_key, content=content)
        # HTTP状态码
        print('http status code:{}'.format(result.status_code))
        # 请求ID。请求ID是本次请求的唯一标识,建议在日志中添加此参数
        print('request_id: {}'.format(result.request_id))
        # hash_crc64_ecma 表示该对象的64位CRC值, 可用于验证上传对象的完整性
        print('crc64: {}'.format(result.hash_crc64_ecma))
    except Exception as e:
        print('fail with unknown error: {}'.format(e))
    
    return url

python请求示例

下载python sdk

import base64
from volcengine.visual.VisualService import VisualService
import json

if __name__ == '__main__':
    visual_service = VisualService()
    # call below method if you dont set ak and sk in $HOME/.volc/config
    visual_service.set_ak('')
    visual_service.set_sk('')

    params = dict()

    form = {
        "image_base64":  base64.b64encode(open(path,'rb').read()).decode(),   # 文件binary 图片/PDF 
        "image_url": "",                  # url
        "version": "v3",                  # 版本
        "page_start": 0,                  # 起始页数
        "page_num": 16,                   # 解析页数
        "table_mode": "html",             # 表格解析模式
        "filter_header": "true"           # 过滤页眉页脚水印
    }

    # 请求
    resp = visual_service.ocr_pdf(form)

    if resp["data"]:
        markdown = resp["data"]["markdown"] # markdown 字符串
        json_data = resp["data"]["detail"] # json格式详细信息

        with open("resp.md", "w") as f:
            f.writelines(markdown)

        json_data = json.loads(json_data)

        # 保存json
        with open("resp.json", "w") as f:
            json.dump(json_data, f, indent=4, ensure_ascii=False)
    else:
        print("request error")