调用百度OCR时遇到的问题(封装到类中的静态成员问题)
当我们调用百度的图像识别OCR时,把百度的官方代码粘过来一般是能直接用的
点击查看代码
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <curl/curl.h>
#include <json/json.h>
#include <fstream>
#include <memory>
std::string client_id = "nMEcgArz8ZzUh*********";
std::string client_secret = "a1fIdfXrGFlV********";
inline size_t onWriteData(void * buffer, size_t size, size_t nmemb, void * userp)
{
std::string * str = dynamic_cast<std::string *>((std::string *)userp);
str->append((char *)buffer, size * nmemb);
return nmemb;
}
std::string getAccessToken()
{
std::string result;
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl)
{
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_URL, "https://aip.baidubce.com/oauth/2.0/token");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
headers = curl_slist_append(headers, "Accept: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
// image 可以通过 getFileBase64Content('C:\fakepath\TestImage.png') 方法获取
// 注意getFileBase64Content方法第二个参数,如果Content-Type是application/x-www-form-urlencoded时,urlencoded请设置为True
std::string data = "grant_type=client_credentials&client_id="+client_id+"&client_secret="+client_secret;
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
res = curl_easy_perform(curl);
}
curl_easy_cleanup(curl);
Json::Value obj;
std::string error;
Json::CharReaderBuilder crbuilder;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
reader->parse(result.data(), result.data() + result.size(), &obj, &error);
return obj["access_token"].asString();
}
int main(int argc, char *argv[])
{
std::string result;
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_URL, ("https://aip.baidubce.com/rest/2.0/ocr/v1/webimage?access_token=" + getAccessToken()).c_str());
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "undefined");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
headers = curl_slist_append(headers, "Accept: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
const char *data = "url=https%3A%2F%2Fbaidu-ai.bj.bcebos.com%2Focr%2Fwebimage.jpeg&detect_language=false&detect_direction=false";
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
res = curl_easy_perform(curl);
std::cout<<result;
}
curl_easy_cleanup(curl);
return (int)res;
}
点击查看代码
std::string ImaginePath="**********";//你的图片路径
std::string imageBase64 = getFileBase64Content(ImaginePath, true);
std::string data = "image=" + imageBase64 + "&detect_language=false&detect_direction=false";
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
点击查看代码
#pragma once
//用于图片识别
#include <QWidget>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <curl/curl.h>
#include <json/json.h>
#include <fstream>
#include <memory>
#include<QFileDialog>
#include "ui_OCRImagine.h"
extern std::string client_id;
extern std::string client_secret;
class OCRImagine : public QWidget
{
Q_OBJECT
public:
OCRImagine(QWidget *parent = Q_NULLPTR);
~OCRImagine();
std::string get_ImagineData(const char*ImaginePath);//获取图片数据
private slots:
void on_PushImagineBtn_clicked();//导入图片
private:
//将服务器返回的 HTTP 响应数据(如 JSON 字符串)保存到 C++ 字符串中
inline size_t onWriteData(void * buffer, size_t size, size_t nmemb, void * userp);
//将传入的图片转化为Base64编码(API要求Base编码传入)
std::string getFileBase64Content(const char * path, bool urlencoded = false);
//获取调用 OCR API 所需的临时访问令牌(access_token),每30天重新授权一次
std::string getAccessToken();
private:
Ui::OCRImagine ui;
};
#include "OCRImagine.h"
std::string client_id = "nMEcgArz8********";
std::string client_secret = "a1fIdfXrGF*************";
OCRImagine::OCRImagine(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
}
OCRImagine::~OCRImagine()
{
}
std::string OCRImagine::get_ImagineData(const char * ImaginePath)
{
SetConsoleOutputCP(CP_UTF8);
SetConsoleCP(CP_UTF8);
std::string result;
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_URL, ("https://aip.baidubce.com/rest/2.0/ocr/v1/webimage?access_token=" + getAccessToken()).c_str());
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "undefined");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
headers = curl_slist_append(headers, "Accept: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
// image 可以通过 getFileBase64Content('C:\fakepath\TestImage.png') 方法获取
// 注意getFileBase64Content方法第二个参数,如果Content-Type是application/x-www-form-urlencoded时,urlencoded请设置为True
std::string imageBase64 = getFileBase64Content(ImaginePath, true);
std::string data = "image=" + imageBase64 + "&detect_language=false&detect_direction=false";
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &OCRImagine::onWriteData);
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
std::cerr << "curl请求失败:" << curl_easy_strerror(res) << std::endl;
}
}
//std::cout << result;
ui.ImagineShow->setText(QString::fromUtf8(result.c_str(),result.length()));
curl_easy_cleanup(curl);
return result;
}
//将服务器返回的 HTTP 响应数据(如 JSON 字符串)保存到 C++ 字符串中
size_t OCRImagine::onWriteData(void * buffer, size_t size, size_t nmemb, void * userp)
{
if (buffer == nullptr || userp == nullptr) return 0;
std::string *response = static_cast<std::string*>(userp);
size_t total = size * nmemb;
response->append(static_cast<char*>(buffer), total);
return total;
}
//将传入的图片转化为Base64编码(API要求Base编码传入)
std::string OCRImagine::getFileBase64Content(const char * path, bool urlencoded)
{
const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
const unsigned int bufferSize = 1024;
unsigned char buffer[bufferSize];
std::ifstream file_read;
file_read.open(path, std::ios::binary);
while (!file_read.eof())
{
file_read.read((char *)buffer, bufferSize * sizeof(char));
int num = file_read.gcount();
int m = 0;
while (num--)
{
char_array_3[i++] = buffer[m++];
if (i == 3)
{
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (i = 0; (i < 4); i++)
{
ret += base64_chars[char_array_4[i]];
}
i = 0;
}
}
}
file_read.close();
if (i)
{
for (j = i; j < 3; j++)
{
char_array_3[j] = '\0';
}
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++)
{
ret += base64_chars[char_array_4[j]];
}
while ((i++ < 3))
{
ret += '=';
}
}
if (urlencoded)
{
ret = curl_escape(ret.c_str(), ret.length());
}
return ret;
}
//获取调用 OCR API 所需的临时访问令牌(access_token),每30天重新授权一次
std::string OCRImagine::getAccessToken()
{
std::string result;
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if (curl == nullptr)
{
std::cerr << "致命错误:curl句柄创建失败!" << std::endl;
return "";
}
else
{
try
{
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_URL, "https://aip.baidubce.com/oauth/2.0/token");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
//curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
headers = curl_slist_append(headers, "Accept: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
std::string data = "grant_type=client_credentials&client_id=" + client_id + "&client_secret=" + client_secret;
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &OCRImagine::onWriteData);
res = curl_easy_perform(curl);//出现问题
//*
if (res != CURLE_OK) {
std::cerr << "获取Token失败: " << curl_easy_strerror(res) << std::endl;
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
return "";
}
curl_slist_free_all(headers); // 释放headers
}
catch (const std::exception& e) {
std::cerr << "getAccessToken异常: " << e.what() << std::endl;
curl_easy_cleanup(curl);
return "";
}
}
Json::Value obj;
std::string error;
Json::CharReaderBuilder crbuilder;
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
bool parseOk=reader->parse(result.data(), result.data() + result.size(), &obj, &error);
if (!parseOk || obj["access_token"].isNull()) {
std::cerr << "Token解析失败: " << error << " | 响应数据: " << result << std::endl;
curl_easy_cleanup(curl);
return "";
}
curl_easy_cleanup(curl);
return obj["access_token"].asString();
}
//导入图片按钮
void OCRImagine::on_PushImagineBtn_clicked()
{
QString File_path = QFileDialog::getOpenFileName(this,
QString::fromLocal8Bit("请选择文件"),
"/", QString::fromLocal8Bit("选择的文件(*.jpg;*.png);"));
ui.ImaginePath->setText(File_path);
QByteArray byteArr = File_path.toUtf8();
this->get_ImagineData(byteArr.constData());
}
浙公网安备 33010602011771号