帮助与文档 > 产品文档 > 文字识别OCR > API 文档

有道智云OCR API说明文档

有道智云OCR API简介

有道智云OCR API接口提供有道的OCR文字识别服务,包含文字片段识别功能。您只需要通过调用有道智云OCR API,传入经过Base64编码的图片,通过POST请求方式,就可以得到相应的文字识别结果。

有道智云OCR API HTTP地址:

http://openapi.youdao.com/ocrapi

有道智云OCR API HTTPS地址:

https://openapi.youdao.com/ocrapi

接口调用参数

调用API需要向接口发送以下字段来访问服务。

字段名类型含义必填备注
imgtext要识别的图片,需要Base64编码True必须是Base64编码
langTypetext要识别的语言类型True目前支持英文:en,和中英混合:zh-en
detectTypetext识别类型,按字识别、按行识别true按字识别:10011;按行识别:10012
imageTypetext图片类型,目前只支持Base64True目前只支持Base64:1,imageType的值为1
appKeytext应用申请的keyTrue可在管理控制台查看
salttext随机数True
signtext签名,通过md5(appkey+img+salt+密钥)生成TrueappKey+img+salt+密钥的MD5值
docTypetext服务器响应类型,目前只支持jsonTruejson

签名生成方法如下: 1、将请求参数中的 appKey(应用ID), img (注意为图片的Base64编码), 随机数 salt密钥 按照 appKey+img+salt+密钥 的顺序拼接得到字符串 str 。 2、对字符串 str 做 md5,得到32位大写的 sign (参考Java生成MD5示例)

注意:

  1. 请先将需要识别的图片转换为 Base64 编码。
  2. 在发送HTTP请求之前需要对各字段做 URL encode。
  3. 在生成签名拼接 appid+img+salt+密钥 字符串时,img 不需要做 URL encode,在生成签名之后,发送 HTTP 请求之前才需要对要发送的待翻译文本字段 img 做URL encode。

输出结果

返回的结果是json格式,包含字段与FROM和TO的值有关,具体说明如下:

字段名类型含义备注
errorCodetext错误返回码一定存在
Resulttext识别结果查询正确时一定存在

按行识别的输出结果和按字识别返回的结果有很大不同。

字段类型字段说明
errorCodetext错误码,一定存在
Resulttext识别结果,查询成功一定存在
+orientationtext图片方向
+regionsjsonarray区域,查询正确一定存在
++linesjsonarray行,查询正确一定存在
+++wordsjsonarray字,查询正确一定存在
++++wordtext识别的字的结果
+++texttext行识别结果
boundingBoxtext段落、行、字的区域位置信息

即识别结果主要在Result中,输出结构为:regions->lines->words.一个文档可能有多个region,代表段落,一个段落有多行,一行有多个字。

每个段落、每行、每个字都有boundingBox,代表能够框住段落、行、字的最大box的位置信息。

boundingBox共八个值:分别是左上角坐标(x,y),右上角坐标(x,y),右下角坐标(x,y), 左下角(x,y)

示例

按字识别的返回结果示例:

{
  "errorCode": "0",
  "Result": {
      "orientation": "Up",
      "textAngle": 0,
      "language": "en",
      "lines": [
          {
              "boundingBox": "30,33,25,10",
              "words": "hello"
          }
      ]
  }
}

其中,orientation 代表方向,textAngle 代表与垂直向上的偏差角度,language 代表识别的语言,lines 代表每行的返回结果;boundingBox 的四个值代表识别的文字左上角的坐标(x,y),宽度和高度;words 代表识别的字

按行识别的返回结果:

{
    "errorCode": "0",   //识别错误码
    "Result": {         //识别结果
        "orientation": "UP",//图像方向
        "regions": [        //段落
        {
            "boundingBox": "90,56,232,56,232,244,90,244",   //段落区域位置信息
            "lines": [      //行
            {
            "boundingBox": "116,56,204,56,204,82,116,82",   //行区域位置信息
            "words": [  //字
                {
                    "boundingBox": "124,54,148,54,148,86,124,86",   //字区域位置信息
                    "word": "静" //字识别结果
                },
                {
                "boundingBox": "156,54,172,53,172,85,156,86",
                "word": "夜"
                },
                {
                "boundingBox": "180,53,204,53,204,85,180,85",
                "word": "思"
                }
            ],
            "text": "静夜思"   //行识别结果
        },
        ...
        ]
        }
        ]
    }
}

即识别结果主要在Result中,输出结构为:regions->lines->words.一个文档可能有多个region,代表段落,一个段落有多行,一行有多个字。

每个段落、每行、每个字都有boundingBox,代表能够框住段落、行、字的最大box的位置信息。

boundingBox共八个值:分别是左上角坐标(x,y),右上角坐标(x,y),右下角坐标(x,y), 左下角(x,y)

支持的语言表

按字识别支持识别语言类型:

语言代码
中英混合zh-en
英文en

按行识别支持识别的语言类型:

语言语言代码
中英繁zh-en
日韩ja-ko
拉丁语系la-all
印地hi
自动识别auto

注意:

  1. lanType 支持 zh-enen ,其中 zh-en 为中英识别,en 参数表示只识别英文。
  2. 若为纯英文识别,zh-en 的识别效果不如 en,请妥善选择。

3.拉丁语系支持的语种包括:葡萄牙、西班牙、法语、意大利语、罗马尼亚、波兰、俄语、荷兰、德语

4.自动识别能够识别除印地语之外的所有语种

注:la-all和auto相比:对于拉丁语系的识别结果更好。纯英文的识别按字识别比按行识别的效果好。

错误代码列表

错误码含义
101缺少必填的参数,出现这个情况还可能是et的值和实际加密方式不对应
102不支持的语言类型
103翻译文本过长
104不支持的API类型
105不支持的签名类型
106不支持的响应类型
107不支持的传输加密类型
108appKey无效,注册账号, 登录后台创建应用和实例并完成绑定, 可获得应用ID和密钥等信息,其中应用ID就是appKey( 注意不是应用密钥)
109batchLog格式不正确
110无相关服务的有效实例
111开发者账号异常
201解密失败,可能为DES,BASE64,URLDecode的错误
202签名检验失败
203访问IP地址不在可访问IP列表
301辞典查询失败
302小语种查询失败
303服务端的其它异常
401账户已经欠费停
411访问频率受限,请稍后访问
412大图片请求过于频繁,请稍后访问
1001无效的OCR类型
1002不支持的OCR image类型
1003不支持的OCR Language类型
1004识别图片过大
1201图片base64解密失败
1301OCR段落识别失败
1411访问频率受限
1412超过最大识别字节数

常见问题及注意事项

  • 返回110

应用没有绑定服务实例,可以新建服务实例,绑定服务实例。

  • 返回108

appKey无效,注册账号, 登录后台创建应用和实例并完成绑定, 可获得应用ID和密钥等信息,其中应用ID就是appKey( 注意不是应用密钥)

  • 返回101

首先确保必填参数齐全,然后,确认参数书写是否正确。

  • 返回202

如果确认 appKeyappSecret 的正确性,仍返回202,一般是编码问题。请确保 img 为UTF-8编码.

常用语言 Demo

Java 示例
Python 示例
C# 示例
PHP 示例
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sun.org.apache.xml.internal.security.utils.Base64;

import outfox.ead.openapi.util.EnDeCriptUtil;

public class OCRDemoForHttp {

  static Logger logger = LoggerFactory.getLogger(OCRDemoForHttp.class);
  public static void main(String[] args) throws Exception {
      Map map = new HashMap<>();
      String url = "http://openapi.youdao.com/ocrapi";
      String appKey = "您的appID";
      String detectType = "10012";
      String imageType = "1";
      String langType = "en";
      String docType = "json";
      String salt = String.valueOf(System.currentTimeMillis());
      String img = getImageStr("图片地址");

      map.put("appKey", appKey);
      map.put("img", img);
      map.put("detectType", detectType);
      map.put("imageType", imageType);
      map.put("langType", langType);
      map.put("salt", salt);
      map.put("docType", docType);
      String sign = md5(appKey + img + salt + "您的应用密钥");
      map.put("sign", sign);
      String result= requestOCRForHttp(url,map);
      System.out.println(result);
  }

  public static String requestOCRForHttp(String url,Map requestParams) throws Exception{
      String result = null;
      CloseableHttpClient httpClient = HttpClients.createDefault();
      /**HttpPost*/
      HttpPost httpPost = new HttpPost(url);
      List params = new ArrayList();
      params.add(new BasicNameValuePair("appKey", requestParams.get("appKey")));
      params.add(new BasicNameValuePair("img", requestParams.get("img")));
      params.add(new BasicNameValuePair("detectType", requestParams.get("detectType")));
      params.add(new BasicNameValuePair("imageType", requestParams.get("imageType")));
      params.add(new BasicNameValuePair("langType", requestParams.get("langType")));
      params.add(new BasicNameValuePair("salt", requestParams.get("salt")));
      params.add(new BasicNameValuePair("sign", requestParams.get("sign")));
      params.add(new BasicNameValuePair("docType", requestParams.get("docType")));
      httpPost.setEntity(new UrlEncodedFormEntity(params,"UTF-8"));
      /**HttpResponse*/
      CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
      try{
          HttpEntity httpEntity = httpResponse.getEntity();
          result = EntityUtils.toString(httpEntity, "utf-8");
          EntityUtils.consume(httpEntity);
      }finally{
          try{
              if(httpResponse!=null){
                  httpResponse.close();
              }
          }catch(IOException e){
              logger.info("## release resouce error ##" + e);
      }
      return result;
  }
  /**
   * 获得图片的Base64编码
   * @param imgFile
   * @return
   */
  public static String getImageStr(String imgFile)
  {//将图片文件转化为字节数组字符串,并对其进行Base64编码处理
      InputStream in = null;
      byte[] data = null;
      //读取图片字节数组
      try
      {
          in = new FileInputStream(imgFile);
          data = new byte[in.available()];
          in.read(data);
          in.close();
      }
      catch (IOException e)
      {
          e.printStackTrace();
      }
      //对字节数组Base64编码
      return Base64.encode(data);//返回Base64编码过的字节数组字符串
  }
  /**
   * 生成32位MD5摘要
   * @param string
   * @return
   */
  public static String md5(String string) {
      if(string == null){
          return null;
      }
      char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
              'A', 'B', 'C', 'D', 'E', 'F'};
      byte[] btInput = string.getBytes();
      try{
          /** 获得MD5摘要算法的 MessageDigest 对象 */
          MessageDigest mdInst = MessageDigest.getInstance("MD5");
          /** 使用指定的字节更新摘要 */
          mdInst.update(btInput);
          /** 获得密文 */
          byte[] md = mdInst.digest();
          /** 把密文转换成十六进制的字符串形式 */
          int j = md.length;
          char str[] = new char[j * 2];
          int k = 0;
          for (byte byte0 : md) {
              str[k++] = hexDigits[byte0 >>> 4 & 0xf];
              str[k++] = hexDigits[byte0 & 0xf];
          }
          return new String(str);
      }catch(NoSuchAlgorithmException e){
          return null;
      }
  }
}
      
#/usr/bin/env python
#coding=utf8

import httplib
import md5
import urllib
import urllib2
import random
import json
import base64

appKey = '您的appKey'
secretKey = '您的密钥'


httpClient = None



try:
    f=open(r'd:\1.png','rb') #二进制方式打开图文件
    img=base64.b64encode(f.read()) #读取文件内容,转换为base64编码
    f.close()

    detectType = '10012'
    imageType = '1'
    langType = 'en'
    salt = random.randint(1, 65536)

    sign = appKey+img+str(salt)+secretKey
    m1 = md5.new()
    m1.update(sign)
    sign = m1.hexdigest()
    data = {'appKey':appKey,'img':img,'detectType':detectType,'imageType':imageType,'langType':langType,'salt':str(salt),'sign':sign}
    data = urllib.urlencode(data)
    req = urllib2.Request('http://openapi.youdao.com/ocrapi',data)

    #response是HTTPResponse对象
    response = urllib2.urlopen(req)
    print response.read()
except Exception, e:
    print e
finally:
    if httpClient:
        httpClient.close()

        
using System;
using System.Web;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;

namespace ConsoleApplication2
{
    using System;
    using System.Collections.Specialized;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Web;
    using System.Security.Cryptography;
    using System.Drawing;

    class Test
    {

        public static void Main() {

            String url = "http://openapi.youdao.com/ocrapi";
            Dictionary dic = new Dictionary();

            string img = ImgToBase64String("d:/1.png");
            string appKey = "your appKey";
            string detectType = "10012";
            string langType = "en";
            String imageType = "1";
            string salt = DateTime.Now.Millisecond.ToString();
            string appSecret = "your appSecret";
            MD5 md5 = new MD5CryptoServiceProvider();
            string md5Str = appKey + img + salt + appSecret;
            byte[] output = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(md5Str));
            string sign = BitConverter.ToString(output).Replace("-", "");
            dic.Add("img", System.Web.HttpUtility.UrlEncode(img));
            dic.Add("appKey", appKey);
            dic.Add("langType", langType);
            dic.Add("detectType", detectType);
            dic.Add("imageType", imageType);
            dic.Add("salt", salt);
            dic.Add("sign", sign);
            string result = Post(url, dic);
            Console.WriteLine(result);

    }

       protected static string ImgToBase64String(string Imagefilename)
    {
      try
      {
        System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(Imagefilename);

        MemoryStream ms = new MemoryStream();
        bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
        byte[] arr = new byte[ms.Length];
        ms.Position = 0;
        ms.Read(arr, 0, (int)ms.Length);
        ms.Close();
        return Convert.ToBase64String(arr);
      }
      catch (Exception ex)
      {
        return null;
      }
    }
        public static string Post(string url,Dictionary dic)
        {
            string result = "";
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded";
            #region 添加Post 参数
            StringBuilder builder = new StringBuilder();
            int i = 0;
            foreach (var item in dic)
            {
                if (i > 0)
                    builder.Append("&");
                builder.AppendFormat("{0}={1}", item.Key, item.Value);
                i++;
            }
            Console.WriteLine(builder.ToString());
            byte[] data = Encoding.UTF8.GetBytes(builder.ToString());
            req.ContentLength = data.Length;
            using (Stream reqStream = req.GetRequestStream())
            {
                reqStream.Write(data, 0, data.Length);
                reqStream.Close();
            }
            #endregion
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            Stream stream = resp.GetResponseStream();
            //获取响应内容
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            }
            return result;
        }


    }
}

        
<?php
define("CURL_TIMEOUT",   2000);
define("URL",            "http://openapi.youdao.com/ocrapi");
define("APP_KEY",         "your app key"); //替换为您的APPKey
define("SEC_KEY",        "your app secret");//替换为您的密钥

//翻译入口
function ocr($img, $imgType, $detectType, $langType)
{
                    $args = array(
        'img' => $img,
        'appKey' => APP_KEY,
        'salt' => rand(10000,99999),
        'imageType' => $imgType,
    'detectType' => $detectType,
        'langType' => $langType,

    );
                    $args['sign'] = buildSign(APP_KEY, $img, $args['salt'], SEC_KEY);
                    $ret = call(URL, $args);
    echo $ret;
                    $ret = json_decode($ret, true);
    return $ret;
}

//加密
function buildSign($appKey, $query, $salt, $secKey)
{/*{{{*/
                    $str = $appKey . $query . $salt . $secKey;
                    $ret = md5($str);
    return $ret;
}/*}}}*/

//发起网络请求
function call($url, $args=null, $method="post", $testflag = 0, $timeout = CURL_TIMEOUT, $headers=array())
{/*{{{*/
                    $ret = false;
                    $i = 0;
    while($ret === false)
    {
        if($i > 1)
            break;
        if($i > 0)
        {
            sleep(1);
        }
                    $ret = callOnce($url, $args, $method, false, $timeout, $headers);
                    $i++;
    }
    return $ret;
}/*}}}*/

function callOnce($url, $args=null, $method="post", $withCookie = false, $timeout = CURL_TIMEOUT, $headers=array())
{/*{{{*/
                    $ch = curl_init();
    if($method == "post")
    {
                    $data = convert($args);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_POST, 1);
    }
    else
    {
                    $data = convert($args);
        if($data)
        {
            if(stripos($url, "?") > 0)
            {
                    $url .= "&$data";
            }
            else
            {
                    $url .= "?$data";
            }
        }
    }
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    if(!empty($headers))
    {
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }
    if($withCookie)
    {
        curl_setopt($ch, CURLOPT_COOKIEJAR, $_COOKIE);
    }
                    $r = curl_exec($ch);
    curl_close($ch);
    return $r;
}/*}}}*/

function convert(&$args)
{/*{{{*/
                    $data = '';
    if (is_array($args))
    {
        foreach ($args as $key=>$val)
        {
            if (is_array($val))
            {
                foreach ($val as $k=>$v)
                {
                    $data .= $key.'['.$k.']='.rawurlencode($v).'&';
                }
            }
            else
            {
                    $data .="$key=".rawurlencode($val)."&";
            }
        }
        return trim($data, "&");
    }
    return $args;
}/*}}}*/
                    $file="d:/1.png";
                    $fp=fopen($file,"r")or die("Can't open file");
                    $img=chunk_split(base64_encode(fread($fp,filesize($file))));//base64编码
fclose($fp);
//调用翻译
ocr($img,"1","10012","en");
?>

        
 
有道智云平台介绍
网易有道旗下一个为开发者、企业和政府机构等提供自然语言翻译、文字识别OCR等服务以及行业解决方案的云服务平台,致力于提供安全、可靠和高效的云服务。
联系方式
联系电话:010-8255-8901
商务合作:
投诉反馈:
地址:北京市海淀区西北旺东路10号院 中关村软件园二期西区7号 网易(北京)公司
微信公众号
 
 
 
©2017 网易公司 京ICP证080268号