阅读本文前先看这篇文章,有curl,openssl,jsoncpp的编译:c++调用百度AI OCR SDK ,本来百度是封装好了c++ SDK调用方法的,所以本文主要研究本质POST的用法。
一.鉴权认证机制
1.百度通用参考:鉴权认证机制
简介
本文档主要针对HTTP API调用者,百度AIP开放平台使用OAuth2.0授权调用开放API,调用API时必须在URL中带上access_token参数,获取Access Token的流程如下:
获取Access Token
请求URL数据格式
向授权服务地址https://aip.baidubce.com/oauth/2.0/token
发送请求(推荐使用POST),并在URL中带上以下参数:
- grant_type: 必须参数,固定为
client_credentials
; - client_id: 必须参数,应用的
API Key
; - client_secret: 必须参数,应用的
Secret Key
;
例如:
https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=Va5yQRHlA4Fq5eR3LT0vuXV4&c
2.c++调用
这里提供我的Key, token有一定的有效期,需要自行管理,当失效时需重新获取
#include <iostream>
#include <curl/curl.h>
#include <json/json.h>
#pragma warning(disable:4996)
//#include "access_token.h"
// libcurl库下载链接:https://curl.haxx.se/download.html
// jsoncpp库下载链接:https://github.com/open-source-parsers/jsoncpp/
// 获取access_token所需要的url
const std::string access_token_url = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials";
// 回调函数获取到的access_token存放变量
// static std::string access_token_result;
/**
* curl发送http请求调用的回调函数,回调函数中对返回的json格式的body进行了解析,解析结果储存在result中
* @param 参数定义见libcurl库文档
* @return 返回值定义见libcurl库文档
*/
static size_t callback(void *ptr, size_t size, size_t nmemb, void *stream) {
// 获取到的body存放在ptr中,先将其转换为string格式
std::string s((char *)ptr, size * nmemb);
// 开始获取json中的access token项目
Json::Reader reader;
Json::Value root;
// 使用boost库解析json
reader.parse(s, root);
std::string* access_token_result = static_cast<std::string*>(stream);
*access_token_result = root["access_token"].asString();
return size * nmemb;
}
/**
* 用以获取access_token的函数,使用时需要先在百度云控制台申请相应功能的应用,获得对应的API Key和Secret Key
* @param access_token 获取得到的access token,调用函数时需传入该参数
* @param AK 应用的API key
* @param SK 应用的Secret key
* @return 返回0代表获取access token成功,其他返回值代表获取失败
*/
int get_access_token(std::string &access_token, const std::string &AK, const std::string &SK) {
CURL *curl;
CURLcode result_code;
int error_code = 0;
curl = curl_easy_init();
if (curl) {
std::string url = access_token_url + "&client_id=" + AK + "&client_secret=" + SK;
curl_easy_setopt(curl, CURLOPT_URL, url.data());
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
std::string access_token_result;
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &access_token_result);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback);
result_code = curl_easy_perform(curl);
if (result_code != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(result_code));
return 1;
}
access_token = access_token_result;
curl_easy_cleanup(curl);
error_code = 0;
}
else {
fprintf(stderr, "curl_easy_init() failed.");
error_code = 1;
}
return error_code;
}
int main()
{
std::string stToken;
get_access_token(stToken, "puMFv72xqCYV2jdcSlXgtFvm", "v5XHtqKXEm0p6ehPZrXIXrftDvocyv1m");
std::cout << "获取Token:" << stToken << std::endl;
return 0;
}
3.获取Token
二、通用文字识别(标准版)
1.百度AI OCR POST 请求:通用文字识别(标准版)
请求说明
请求示例
HTTP 方法:POST
请求URL: https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic
URL参数:
参数 | 值 |
---|---|
access_token | 通过API Key和Secret Key获取的access_token,参考“Access Token获取” |
Header如下:
参数 | 值 |
---|---|
Content-Type | application/x-www-form-urlencoded |
2.获取图片Base64
我们把这张图片通过在线转换获取base64
3.c++ POST方法
建立ssl连接时出现以下错误。“对等证书不能使用已知的CA证书进行身份验证”
先关闭证书的curl的验证
curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,FALSE);
#include <iostream>
#include <curl/curl.h>
#include <string>
// libcurl库下载链接:https://curl.haxx.se/download.html
// jsoncpp库下载链接:https://github.com/open-source-parsers/jsoncpp/
const static std::string request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic";
static std::string generalBasic_result;
/**
* curl发送http请求调用的回调函数,回调函数中对返回的json格式的body进行了解析,解析结果储存在全局的静态变量当中
* @param 参数定义见libcurl文档
* @return 返回值定义见libcurl文档
*/
static size_t callback2(void *ptr, size_t size, size_t nmemb, void *stream) {
// 获取到的body存放在ptr中,先将其转换为string格式
generalBasic_result = std::string((char *)ptr, size * nmemb);
return size * nmemb;
}
/**
* 通用文字识别
* @return 调用成功返回0,发生错误返回其他错误码
*/
int generalBasic(std::string &json_result, const std::string &access_token) {
std::string url = request_url + "?access_token=" + access_token;
CURL *curl = NULL;
CURLcode result_code;
int is_success;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_easy_setopt(curl, CURLOPT_URL, url.data());
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_httppost *post = NULL;
curl_httppost *last = NULL;
curl_formadd(&post, &last, CURLFORM_COPYNAME, "image", CURLFORM_COPYCONTENTS, "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFcAAAAUCAYAAAD4BKGuAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJzSURBVFhH7ZfbkcMgDEW3R3fiRtwHZdAFXbgDFpmXEJIsO85OZjYfdyYGR48jCZKfZVniV1RrdCFEt3J7dn3hclpdDPse9/01wF+4jFYXElgfN2ZP1eZjcGt7ZuDCSEDVqIizZKjtBRdXvEe0+W7Hb7C2RV+ecTCzUCx+y2vVb32muhAXrxxbjnNca3bPVPwOcDEEUTVgnIQ2Pm3EslrQhtHLHZTewZA0uMiXXjRZh8/B9hpXLr7Dl35sNLgDWCbwKdEBLv+d/r0QQ+lA3BHNpwqKJCDBfQBs7lAyodUunQIzXARqHAeqNKaewE3PeXS5M6qMUwrMFZDSuFG/IngWLhpbocgWgU82DgoWZIPLnGsWoSRrV9OOqesQcIVFg58mAtSKzRRsgvsMWIhj6vjDlwDQBlfuHlVDktUGhlGLltckuLi4Obn+zMYz+L3ZGFStmLNEJia49Uxhx1oR6SDcpXi/doMMt78LMTiuk7l323GkvHtBmx9BQbzq2W2CixJ7BW4rUkk0w+w2VbhoP0sJusXbpUK4oaNRzibhT+EmNYCugOb2pDFDx5MKi4ELku1eFECzTIIJbu24B+COic9jdgbB8g712zteT9SkgwXhUPxNBTfBfeRCq+vogiHVfxdczecl1Y5tzVY05EfeP4d788Zl4TIXW9H74IJe/znWJ8A4wTa46UMNOElNDAox/YmwJfNeuGg96d4FJ/zNlWSGm9QrxwSeNP3Y/zS4SS3GMxsX1G2Sjr4CFzQAlvTBcEE9Bz1xTbhI4hRIcFN89TsD3Cx0fmHRy+JD4Q53iBkwyRnZ7sW6qGSDgftPBUUzNopNS/wFOn1L0FSx0H8AAAAASUVORK5CYII=", CURLFORM_END);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback2);
result_code = curl_easy_perform(curl);
if (result_code != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(result_code));
is_success = 1;
return is_success;
}
json_result = generalBasic_result;
curl_easy_cleanup(curl);
is_success = 0;
}
else {
fprintf(stderr, "curl_easy_init() failed.");
is_success = 1;
}
return is_success;
}
int main()
{
std::string stToken="24.adc315cddc50deb56f96fd35d60badf1.2592000.1621131811.282335-17594920";
/*get_access_token(stToken,"puMFv72xqCYV2jdcSlXgtFvm","v5XHtqKXEm0p6ehPZrXIXrftDvocyv1m");
std::cout << "获取Token:"<<stToken << std::endl;*/
std::cout << "开始OCR通用识别!" << std::endl;
std::string stBack;
generalBasic(stBack, stToken);
std::cout << "返回值:" << stBack << std::endl;
return 0;
}
4.识别效果
项目案例下载:C++ POST请求调用百度AI OCR
/**************************************************************************************************************************************************************************************************************************************/
方法2:提供base64转换方法
//#include <iostream>
//#include <curl/curl.h>
//#include <json/json.h>
//#pragma warning(disable:4996)
//
//// libcurl库下载链接:https://curl.haxx.se/download.html
//// jsoncpp库下载链接:https://github.com/open-source-parsers/jsoncpp/
//// 获取access_token所需要的url
//const std::string access_token_url = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials";
//// 回调函数获取到的access_token存放变量
//// static std::string access_token_result;
///**
// * curl发送http请求调用的回调函数,回调函数中对返回的json格式的body进行了解析,解析结果储存在result中
// * @param 参数定义见libcurl库文档
// * @return 返回值定义见libcurl库文档
// */
//static size_t callback(void *ptr, size_t size, size_t nmemb, void *stream) {
// // 获取到的body存放在ptr中,先将其转换为string格式
// std::string s((char *)ptr, size * nmemb);
// // 开始获取json中的access token项目
// Json::Reader reader;
// Json::Value root;
// // 使用boost库解析json
// reader.parse(s, root);
// std::string* access_token_result = static_cast<std::string*>(stream);
// *access_token_result = root["access_token"].asString();
// return size * nmemb;
//}
//
///**
// * 用以获取access_token的函数,使用时需要先在百度云控制台申请相应功能的应用,获得对应的API Key和Secret Key
// * @param access_token 获取得到的access token,调用函数时需传入该参数
// * @param AK 应用的API key
// * @param SK 应用的Secret key
// * @return 返回0代表获取access token成功,其他返回值代表获取失败
// */
//int get_access_token(std::string &access_token, const std::string &AK, const std::string &SK) {
// CURL *curl;
// CURLcode result_code;
// int error_code = 0;
// curl = curl_easy_init();
// if (curl) {
// std::string url = access_token_url + "&client_id=" + AK + "&client_secret=" + SK;
// curl_easy_setopt(curl, CURLOPT_URL, url.data());
// curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
// curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
// std::string access_token_result;
// curl_easy_setopt(curl, CURLOPT_WRITEDATA, &access_token_result);
// curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback);
// result_code = curl_easy_perform(curl);
// if (result_code != CURLE_OK) {
// fprintf(stderr, "curl_easy_perform() failed: %s\n",
// curl_easy_strerror(result_code));
// return 1;
// }
// access_token = access_token_result;
// curl_easy_cleanup(curl);
// error_code = 0;
// }
// else {
// fprintf(stderr, "curl_easy_init() failed.");
// error_code = 1;
// }
// return error_code;
//}
//int main()
//{
// std::string stToken;
// get_access_token(stToken, "puMFv72xqCYV2jdcSlXgtFvm", "v5XHtqKXEm0p6ehPZrXIXrftDvocyv1m");
// std::cout << "获取Token:" << stToken << std::endl;
// //stToken = "24.adc315cddc50deb56f96fd35d60badf1.2592000.1621131811.282335-17594920"
// return 0;
//}
// base64转换
#include "base64.h"
#include <string>
#include <iostream>
#include "base64.h"
#include <fstream>
#include <stdlib.h>
using namespace std;
std::string GetBase64(std::string _filePath);
// 通用识别
#include <iostream>
#include <curl/curl.h>
#include <string>
// libcurl库下载链接:https://curl.haxx.se/download.html
// jsoncpp库下载链接:https://github.com/open-source-parsers/jsoncpp/
const static std::string request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic";
static std::string generalBasic_result;
/**
* curl发送http请求调用的回调函数,回调函数中对返回的json格式的body进行了解析,解析结果储存在全局的静态变量当中
* @param 参数定义见libcurl文档
* @return 返回值定义见libcurl文档
*/
static size_t callback2(void *ptr, size_t size, size_t nmemb, void *stream) {
// 获取到的body存放在ptr中,先将其转换为string格式
generalBasic_result = std::string((char *)ptr, size * nmemb);
return size * nmemb;
}
/**
* 通用文字识别
* @return 调用成功返回0,发生错误返回其他错误码
*/
int generalBasic(std::string &json_result, const std::string &access_token) {
std::string url = request_url + "?access_token=" + access_token;
CURL *curl = NULL;
CURLcode result_code;
int is_success;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_easy_setopt(curl, CURLOPT_URL, url.data());
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_httppost *post = NULL;
curl_httppost *last = NULL;
std::string stBase64 = GetBase64("CMYK 红.png");
curl_formadd(&post, &last, CURLFORM_COPYNAME, "image", CURLFORM_COPYCONTENTS,stBase64.c_str(), CURLFORM_END);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback2);
result_code = curl_easy_perform(curl);
if (result_code != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(result_code));
is_success = 1;
return is_success;
}
json_result = generalBasic_result;
curl_easy_cleanup(curl);
is_success = 0;
}
else {
fprintf(stderr, "curl_easy_init() failed.");
is_success = 1;
}
return is_success;
}
std::string GetBase64(std::string _filePath)
{
fstream f, f2;
f.open(_filePath, ios::in | ios::binary);//"c:\\ocr.jpg"
f.seekg(0, std::ios_base::end);
std::streampos sp = f.tellg();
int size = sp;
cout << size << endl;
char* buffer = (char*)malloc(sizeof(char)*size);
f.seekg(0, std::ios_base::beg);//把文件指针移到到文件头位置
f.read(buffer, size);
cout << "file size:" << size << endl;
string imgBase64 = base64_encode(buffer, size);
cout << "img base64 encode size:" << imgBase64 << endl;
f.close();
return imgBase64;
}
int main()
{
std::string stToken="24.adc315cddc50deb56f96fd35d60badf1.2592000.1621131811.282335-17594920";
/*get_access_token(stToken,"puMFv72xqCYV2jdcSlXgtFvm","v5XHtqKXEm0p6ehPZrXIXrftDvocyv1m");
std::cout << "获取Token:"<<stToken << std::endl;*/
std::cout << "开始OCR通用识别!" << std::endl;
std::string stBack;
generalBasic(stBack, stToken);
std::cout << "返回值:" << stBack << std::endl;
getchar();
return 0;
}
//int main(int argc, char** argv)
//{
// GetBase64("c:\\1.png");
//}