接上文:libcurl库的介绍和使用,并调用libcurl库编程访问百度主页
1.编程连通翔云平台OCR后台
购买了翔云平台人脸识别接口后,根据其提供的API文档编写下面测试代码,查看翔云后台返回数据
#include <stdio.h>
#include <curl/curl.h>
#include<string.h>
#include<stdlib.h>
#define true 1
#define false 0
typedef unsigned int bool;
size_t readData(void *ptr, size_t size, size_t nmemb, void *stream)
{
char buf[10240] = {'\0'};
strncpy(buf, ptr, 1024);
printf("=========================get Data=====================\n");
printf("%s\n",buf);
}
bool postUrl()
{
CURL *curl;
CURLcode res;
char *postString;
char img1[12];
char img2[12];
char *key = "xxx";
char *secret = "xxx";
int typeId = 21;
char *format = "xml";
postString = (char *)malloc(strlen(key)+strlen(secret)+2048);
sprintf(postString, "&img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s",
"","",key,secret,21,format);//按API文档所示 6个都要有
curl = curl_easy_init();
if (curl)
{
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt"); // 指定cookie文件
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "postString"); // 指定post内容 这里是上面拼接的字符串
curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do"); // 指定url 就是翔云接口地址
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, readData); //设置回调函数把有效读取的字符打印出来
res = curl_easy_perform(curl);
printf("OK:%d\n",res);
curl_easy_cleanup(curl);
}
return true;
}
int main(void)
{
postUrl();
}
编译,运行:
gcc demo2.c -I ./curl-7.71.1/_install/include/ -L ./curl-7.71.1/_install/lib/ -lcurl
ok:1
证明失败了,正常应该返回200,没有跟翔云的后台接通,回调函数没有打印后台返回来的数据。
我们在上文编译的时候误以为编译出来默认是支持SSL的,实际上不支持。而翔云接口是https:开头的,需要选择支持SSL。
于是我们需要对libcurl库重新编译,使编译出来的库支持https访问
2.尝试编译libcurl库支持SSL(也就是支持https访问)
那我们就要回到/curl-7.71.1
路径下,删除_install
上次编译出来的文件夹,重新编译支持SSL的库。由/docs/INSTALL.md
我们可以得知要想支持SSL,就得./configure --with-ssl
。
./configure --prefix=$PWD/_install --with-ssl
于是我们还是想在当前目录下_install文件夹安装
cheking for SSL_connect in -lssl... (cached)no no
configure:error:openSSL libs and/or directories were not found where specified!
编译错误,意思是想要让curl支持https访问,需要ssl依赖库openSSL,也就是需要系统中已经安装好了openSSL。
3.安装SSL依赖库openSSL
回到httpHandler目录下使用wget指令安装openssl
wget https://www.openssl.org/source/openssl-1.1.1a.tar.gz
解压:
tar xvf openssl-1.1.1a.tar.gz
为了避免到时候编译这个curl又要去配置SSL这个库,我们直接把SSL安装到默认的系统位置去,
直接在/openssl-1.1.1a/目录
下
配置, 编译,安装:
./config
make
sudo make install
4.重新编译支持SSL的libcurl库(也就是支持https访问)
回到/curl-7.71.1/
目录下重新进行配置,编译,安装:
./configure --prefix=$PWD/_install --with-ssl
make
make install
现在编译出来的就是最新的支持https访问的curl库
然后重新编译demo2.c
可以看到此时时能接收到翔云后台返回数据的
而产品类型错误原因只是:代码中没有传入图片给它识别
5.加入图片base64编码,最终实现两张图片人脸识别对比
在Linux下生成图片的base64编码:
base64 photo.jpg
下面是实现把生成的base64流写到tmpFile1文件内
system("base64 zhu1.jpg > tmpFile1");//把生成的base64编码的数据保存到tmpFile1中
int fdPic1 = open("./tmpFile1",O_RDWR);//可读可写方式打开文件
int fileLenPic1 = lseek(fdPic1,0,SEEK_END);//计算文件大小
lseek(fdPic1,0,SEEK_SET); //移动光标到头
char* bufPic1 = (char* )malloc(fileLenPic1+8);//开辟空间
memset(bufPic1,'\0',fileLenPic1+8);
read(fdPic1,bufPic1,fileLenPic1); //把文件内容度进取buf中
//printf("%s\n",buf); //打印出来
close(fdPic1);
demo4.c 封装成函数,最终实现两张图片人脸识别对比:
#include <stdio.h>
#include <curl/curl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define true 1
#define false 0
typedef unsigned int bool;
char buf[1024]= {'\0'};
size_t readData( void *ptr, size_t size, size_t nmemb, void *stream)
{
strncpy(buf,ptr,1024);
printf("%s\n",buf);
}
char * getImg(char *file)
{
char * bufimg;
char cmd[128] = {'\0'};
sprintf(cmd,"base64 %s > tmpfile",file);//> 将生成的base64流数据导入到tmpfile这个文件中
system(cmd);
int fd = open("./tmpfile",O_RDWR);
int filelen = lseek(fd,0,SEEK_END); //计算文件大小
lseek(fd,0,SEEK_SET); //移动光标到头
bufimg = (char *)malloc(filelen);
read(fd,bufimg,filelen);
close(fd);
system("rm -rf tmpfile");//每调用一次结束后,删除这个文件夹
return bufimg;//返回读到的base64编码
}
bool postUrl( )
{
CURL *curl;
CURLcode res;
char *param;
char img1[10];
char img2[10];
char * key = "xxx";
char * secret ="xxx";
int typeId = 21;
char *format ="xml";
char *bufimg1 = getImg("./lit1.jpg");
char *bufimg2 = getImg("./lit2.jpg");
int len = (strlen(bufimg1)+strlen(bufimg2)+strlen(key)+strlen(secret)+sizeof(typeId)+strlen(format) + 10);
param = (char *)malloc(len);
sprintf(param,"&img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s",bufimg1,bufimg2,key,secret,typeId,format);//顺序不能变
curl = curl_easy_init();//初始化
if (curl)
{
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, param); // 传参
curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do"); // 访问的接口地址
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,readData );//将https返回的信息返回到readData这个函数
res = curl_easy_perform(curl);//执行请求
printf("OK:%d\n",res);
if(strstr(buf,"是")!= NULL)
{
printf("人脸识别成功\n");
}
curl_easy_cleanup(curl);//释放内存
}
return true;
}
int main(void)
{
postUrl();
}
上传自己的两张照片到当前目录,编译运行:
返回:是
则代表识别成功,是同一个人。