Browse Source

baidu api

duanjianjun 2 years ago
parent
commit
aca68cf25d

+ 336 - 0
MFCApplication1/Base64.cpp

@@ -0,0 +1,336 @@
+/************************************************
+*						*
+* CBase64.cpp					*
+* Base 64 de- and encoding class		*
+*						*
+* ============================================  *
+*						*
+* This class was written on 28.05.2003		*
+* by Jan Raddatz [jan-raddatz@web.de]		*
+*						*
+* ============================================  *
+*						*
+* Copyright (c) by Jan Raddatz			*
+* This class was published @ codeguru.com	*
+* 28.05.2003					*
+*						*
+************************************************/
+#include "pch.h"
+#include "Base64.h"
+
+char CBase64Coder::ch64[] = {
+	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+	'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+	'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+	'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '='
+};
+
+CBase64Coder::CBase64Coder()
+{
+	buf = NULL;
+	size = 0;
+}
+
+CBase64Coder::~CBase64Coder()
+{
+	if (buf)
+	{
+		free(buf);
+		buf = NULL;
+	}
+}
+
+void CBase64Coder::allocMem(int NewSize)
+{
+	if (buf)
+		buf = (char*)realloc(buf, NewSize);
+	else
+		buf = (char*)malloc(NewSize);
+	memset(buf, 0, NewSize);
+}
+
+const  char* CBase64Coder::encode(const string& buffer)
+{
+	return encode(buffer.c_str(), buffer.length());
+}
+
+const char* CBase64Coder::encode(const char* buffer, int buflen)
+{
+#ifdef _DEBUG
+	DWORD start, finish;
+	start = GetTickCount();
+#endif
+	int nLeft = 3 - buflen % 3;
+	//根据BASE64算法,总长度会变成原来的4/3倍
+	//所以内存分配=length*4/3并加1位作为结束符号(0)
+	size = calc_base64_len(buflen);
+	allocMem(size + 1);
+	//临时变量,
+	int index = 0;
+	char *pOut = buf;
+	while (buflen - index >= 3)
+	{
+		const char * p1 = buffer + index;
+		const char * p2 = p1 + 1;
+		const char * p3 = p2 + 1;
+
+		char c1 = ((*p1) & (0xFC)) >> 2;
+		char c2 = ((*p1) & (0x03)) << 4 | ((*p2) & 0xF0) >> 4;
+		char c3 = ((*p2) & (0x0F)) << 2 | ((*p3) & 0xC0) >> 6;
+		char c4 = (*p3) & (0x3F);
+
+		*(pOut++) = _getBase64Char(c1);
+		*(pOut++) = _getBase64Char(c2);
+		*(pOut++) = _getBase64Char(c3);
+		*(pOut++) = _getBase64Char(c4);
+
+		index += 3;
+	}
+
+	int last = buflen - index;
+	if (last == 1)
+	{
+		const char * p1 = buffer + index;
+		char c1 = ((*p1) & (0xFC)) >> 2;
+		char c2 = ((*p1) & (0x03)) << 4;
+		*(pOut++) = _getBase64Char(c1);
+		*(pOut++) = _getBase64Char(c2);
+		*(pOut++) = '=';
+		*(pOut++) = '=';
+
+	}
+	else if (last == 2)
+	{
+		const char * p1 = buffer + index;
+		const char * p2 = p1 + 1;
+		char c1 = ((*p1) & (0xFC)) >> 2;
+		char c2 = ((*p1) & (0x03)) << 4 | ((*p2) & 0xF0) >> 4;
+		char c3 = ((*p2) & (0x0F)) << 2;
+
+		*(pOut++) = _getBase64Char(c1);
+		*(pOut++) = _getBase64Char(c2);
+		*(pOut++) = _getBase64Char(c3);
+		*(pOut++) = '=';
+		//*(pOut++)='=';  
+	}
+#ifdef _DEBUG
+	finish = GetTickCount();
+	//TRACE("func Base64Encode spend %d ms\n", finish - start);
+#endif
+	return buf;
+}
+
+const char* CBase64Coder::decode(const char* buffer, int Length)
+{
+#ifdef _DEBUG
+	DWORD start, finish;
+	start = GetTickCount();
+#endif
+	int length = Length;
+	if (length % 4 != 0)
+		return NULL;
+	int nLen = calc_data_len(buffer,Length);
+	size = nLen;
+	allocMem(size + 1);
+
+	int dec = 0;
+	while (buffer[Length - 1 - dec] == '=')
+	{
+		dec++;
+	}
+
+
+	int real_len = length - dec;
+	int index = 0;
+	char *pOut = buf;
+	while (real_len - index >= 4)
+	{
+		const char * p1 = buffer + index;
+		const char * p2 = p1 + 1;
+		const char * p3 = p2 + 1;
+		const char * p4 = p3 + 1;
+
+		char c1 = BinSearch(*p1);
+		if (c1 == -1)
+		{
+			return NULL;
+		}
+		char c2 = BinSearch(*p2);
+		if (c2 == -1)
+		{
+			return NULL;
+		}
+		char c3 = BinSearch(*p3);
+		if (c3 == -1)
+		{
+			return NULL;
+		}
+		char c4 = BinSearch(*p4);
+		if (c4 == -1)
+		{
+			return NULL;
+		}
+		
+
+		*(pOut++) = (c1) << 2 | ((c2)&(0x30)) >> 4;
+		*(pOut++) = ((c2)&(0xF)) << 4 | ((c3)&(0x3C)) >> 2;
+		*(pOut++) = ((c3)&(0x03)) << 6 | (c4)&(0x3F);
+		index += 4;
+	}
+
+	int last = real_len - index;
+	if (last == 2)
+	{
+		const char * p1 = buffer + index;
+		const char * p2 = p1 + 1;
+
+		char c1 = BinSearch(*p1);
+		char c2 = BinSearch(*p2);
+
+		*(pOut++) = (c1) << 2 | ((c2)&(0x30)) >> 4;
+
+	}
+	else if (last == 3)
+	{
+		const char * p1 = buffer + index;
+		const char * p2 = p1 + 1;
+		const char * p3 = p2 + 1;
+
+		char c1 = BinSearch(*p1);
+		char c2 = BinSearch(*p2);
+		char c3 = BinSearch(*p3);
+
+		*(pOut++) = (c1) << 2 | ((c2)&(0x30)) >> 4;
+		*(pOut++) = ((c2)&(0x0F)) << 4 | ((c3)&(0x30)) >> 2;
+	}
+#ifdef _DEBUG
+	finish = GetTickCount();
+	TRACE("func Base64Decode spend %d ms\n", finish - start);
+#endif
+	return buf;
+}
+
+//采用二分法查找p在ch64数组中的位置,并返回。如果找不到则返回-1
+int CBase64Coder::BinSearch(char p)
+{
+	/*if (p >= 'A' && p <= 'Z')
+		return (p - 'A');
+	else if (p >= 'a' && p <= 'z')
+		return (p - 'a' + 26);
+	else if (p >= '0' && p <= '9')
+		return (p - '0' + 26 + 26);
+	else if (p == '+')
+		return 62;
+	else if (p == '/')
+		return 63;
+	else if (p == '=')
+		return 64;*/
+	switch (p)
+	{
+	case 'A':
+	case 'B':
+	case 'C':
+	case 'D':
+	case 'E':
+	case 'F':
+	case 'G':
+	case 'H':
+	case 'I':
+	case 'J':
+	case 'K':
+	case 'L':
+	case 'M':
+	case 'N':
+	case 'O':
+	case 'P':
+	case 'Q':
+	case 'R':
+	case 'S':
+	case 'T':
+	case 'U':
+	case 'V':
+	case 'W':
+	case 'X':
+	case 'Y':
+	case 'Z':
+		return p - 'A';
+	case 'a':
+	case 'b':
+	case 'c':
+	case 'd':
+	case 'e':
+	case 'f':
+	case 'g':
+	case 'h':
+	case 'i':
+	case 'j':
+	case 'k':
+	case 'l':
+	case 'm':
+	case 'n':
+	case 'o':
+	case 'p':
+	case 'q':
+	case 'r':
+	case 's':
+	case 't':
+	case 'u':
+	case 'v':
+	case 'w':
+	case 'x':
+	case 'y':
+	case 'z':
+		return p - 'a' + 26;
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+		return p - '0' + 52;
+	case '+':
+		return 62;
+	case '/':
+		return 63;
+	case '=':
+		return 64;
+
+	}
+	return -1;
+}
+
+int CBase64Coder::calc_base64_len(int data_len)
+{
+	int last = data_len * 8 % 6;
+	if (last == 0)
+	{
+		return data_len * 8 / 6;
+	}
+	else
+	{
+		int base64_len = data_len * 8 / 6 + 1;
+		base64_len += (last == 2 ? 2 : 1);
+		return base64_len;
+	}
+}
+
+int CBase64Coder::calc_data_len(const char * base64, int base64_len)
+{
+	int dec = 0;
+	while (base64[base64_len - 1 - dec] == '=')
+	{
+		dec++;
+	}
+
+	return ((base64_len - dec) * 6) / 8;
+}
+
+char CBase64Coder::_getBase64Char(char c)
+{
+	return ch64[c];
+}

+ 34 - 0
MFCApplication1/Base64.h

@@ -0,0 +1,34 @@
+#ifndef _BASE64_H_
+#define _BASE64_H_
+
+#include<string>
+using namespace std;
+
+//#include <conf.h>
+class CBase64Coder
+{
+private:
+	static char ch64[];
+	char* buf;
+	int size;
+
+private:
+	static int BinSearch(char p);
+	int calc_base64_len(int data_len);
+	int calc_data_len(const char * base64, int base64_len);
+	char _getBase64Char(char c);
+	void allocMem(int NewSize);
+
+public:
+	int GetSize()
+	{
+		return size;
+	}
+	CBase64Coder();
+	~CBase64Coder();
+	const char* encode(const string& message);
+	const char* encode(const char* buffer, int buflen);
+	const char* decode(const char* buffer, int Length);
+};
+
+#endif

+ 27 - 0
MFCApplication1/BaseUtility.cpp

@@ -4,6 +4,9 @@
 #include <comdef.h>
 #include <afxdb.h>
 #include <regex>
+#include <iostream>
+#include <fstream>
+#include "Base64.h"
 
 typedef basic_string<char>::size_type S_T;
 
@@ -1197,4 +1200,28 @@ CString GetAppPath()
 		strRetun = strRetun.Left(pos);
 	}
 	return strRetun;
+}
+
+string GetImageEncodeString(string strPath)
+{
+	ifstream is(strPath.c_str(), ifstream::in | ios::binary);
+	is.seekg(0, is.end);
+	int length = is.tellg();
+	is.seekg(0, is.beg);
+
+	char *buffer = new char[length];
+	is.read(buffer, length);
+	//主要注意这一句是利用base64.h文件中的编码函数将buffer编码为base64码
+	CBase64Coder base64;
+	std::string strImg = base64.encode(buffer, length);
+	string strTemp = "data:image/jpeg;base64,";
+	strTemp.append(strImg);
+	//打印img看一下
+	string strEncode = UrlEncode(strTemp);
+
+	//删除buffer
+	delete[]buffer;
+	//关闭指针
+	is.close();
+	return strTemp;
 }

+ 3 - 1
MFCApplication1/BaseUtility.h

@@ -170,4 +170,6 @@ tstring FormatInt32Value(int nValue);
 tstring FormatInt64Value(__int64 nValue);
 tstring FormatFloatValue(double fValue);
 string FormatFloatValue2(double fValue);
-CString GetAppPath();
+CString GetAppPath();
+
+string GetImageEncodeString(string strPath);

+ 1 - 0
MFCApplication1/CvxText.h

@@ -64,4 +64,5 @@ int cutPaper(int pageNum, std::string strJsonPath, std::string strPaperPath, std
 
 
 int PareseModeJson(preinfo::templatesInfo&  temeplatInfo);
+
 #endif // PUTTEXT_H_

+ 2 - 0
MFCApplication1/MFCApplication1.vcxproj

@@ -192,6 +192,7 @@
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClInclude Include="AssignWords.h" />
+    <ClInclude Include="Base64.h" />
     <ClInclude Include="BaseUtility.h" />
     <ClInclude Include="Buffers.h" />
     <ClInclude Include="Config.h" />
@@ -207,6 +208,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="AssignWords.cpp" />
+    <ClCompile Include="Base64.cpp" />
     <ClCompile Include="BaseUtility.cpp" />
     <ClCompile Include="Buffers.cpp" />
     <ClCompile Include="Config.cpp" />

+ 6 - 0
MFCApplication1/MFCApplication1.vcxproj.filters

@@ -54,6 +54,9 @@
     <ClInclude Include="Config.h">
       <Filter>头文件</Filter>
     </ClInclude>
+    <ClInclude Include="Base64.h">
+      <Filter>源文件</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="MFCApplication1.cpp">
@@ -83,6 +86,9 @@
     <ClCompile Include="Config.cpp">
       <Filter>源文件</Filter>
     </ClCompile>
+    <ClCompile Include="Base64.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="MFCApplication1.rc">

+ 67 - 1
MFCApplication1/MFCApplication1Dlg.cpp

@@ -16,6 +16,7 @@
 #include <io.h>
 #include "Buffers.h"
 #include "Config.h"
+#include <curl/curl.h>
 
 #if defined(GNUC)
 #pragma GCC diagnostic push
@@ -203,8 +204,73 @@ DWORD WINAPI ProcessThread(void *param)
 	return 0L;
 }
 
+const static std::string request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/handwriting";
+static std::string handwriting_result;
+/**
+* curl发送http请求调用的回调函数,回调函数中对返回的json格式的body进行了解析,解析结果储存在全局的静态变量当中
+* @param 参数定义见libcurl文档
+* @return 返回值定义见libcurl文档
+*/
+static size_t callback(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+	char * pData = (char *)ptr;
+	handwriting_result.append(pData, size * nmemb);
+
+	// 获取到的body存放在ptr中,先将其转换为string格式
+	//handwriting_result = std::string((char *)ptr, size * nmemb);
+	return size * nmemb;
+}
+
+/**
+* 手写文字识别
+* @return 调用成功返回0,发生错误返回其他错误码
+*/
+int handwriting(string strImage, std::string &json_result, const std::string &access_token)
+{
+	handwriting_result = "";
+	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_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, strImage.c_str(), CURLFORM_END);
+
+		curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
+		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));
+			is_success = 1;
+			return is_success;
+		}
+		UTF8toANSI(handwriting_result);
+		json_result = handwriting_result;
+		curl_easy_cleanup(curl);
+		is_success = 0;
+	}
+	else 
+	{
+		fprintf(stderr, "curl_easy_init() failed.");
+		is_success = 1;
+	}
+	return is_success;
+}
+
 int IdentifyCallback(result::spinfo& pinfo, void* param)
 {
+	string strToken = "24.086aba1dfaa5d4fdba74f2c62b591b35.2592000.1668825495.282335-21782130";
+	string strResult;
+	string strEncode = GetImageEncodeString("d:\\202210122100_0001.jpg");
+	handwriting(strEncode, strResult, strToken);
+
 	CMFCApplication1Dlg* pWnd = (CMFCApplication1Dlg*)theApp.m_pMainWnd;
 	if (pinfo.choiceRes.size() < 3 || pinfo.vecUrlAPath.size() == 0)
 	{
@@ -378,7 +444,7 @@ END_MESSAGE_MAP()
 BOOL CMFCApplication1Dlg::OnInitDialog()
 {
 	CDialogEx::OnInitDialog();
-
+	
 	// 将“关于...”菜单项添加到系统菜单中。
 
 	// IDM_ABOUTBOX 必须在系统命令范围内。