当前位置:网站首页>使用libcurl将Opencv Mat的图像上传到文件服务器,基于post请求和ftp协议两种方法
使用libcurl将Opencv Mat的图像上传到文件服务器,基于post请求和ftp协议两种方法
2022-08-02 14:09:00 【虹夭】
基于post请求的
基于post请求的方法主要是上传到比如装了nginx-upload-module的nginx服务器上,url参数传文件所在目录,底下的curl_formadd里添加文件名。
不过nginx-upload-module不会把文件文件名,而是保存成名字为00000000xx
这样的文件10位数字命名的文件,防止上传文件冲突,需要你自己写php或python脚本把文件搬运到正确的位置或者重命名。
设计的好像挺有道理的(倒是给蓝狗提供个脚本呗)。
size_t writer(char *data, size_t size, size_t nmemb, string *writerData) {
if (writerData == nullptr)
return 0;
size_t len = size * nmemb;
writerData->append(data, len);
return len;
}
void postUpLoad(const cv::Mat &img, const char *url) {
vector<uchar> vec_Img;
vector<int> vecCompression_params;
vecCompression_params.push_back(cv::IMWRITE_JPEG_QUALITY);
vecCompression_params.push_back(90);
imencode(".jpg", img, vec_Img, vecCompression_params);
CURL *curl;
CURLcode res;
string buffer;
struct curl_httppost *post = nullptr;
struct curl_httppost *last = nullptr;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_POST, 1);
struct curl_slist *chunk = nullptr;
chunk = curl_slist_append(chunk, "Accept:");
chunk = curl_slist_append(chunk, "Authorization: Token ");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
curl_formadd(&post, &last,
CURLFORM_COPYNAME, "photo",
CURLFORM_BUFFER, "photo.jpg",
CURLFORM_BUFFERPTR, vec_Img.data(),
CURLFORM_BUFFERLENGTH, vec_Img.size(),
CURLFORM_CONTENTTYPE, "image/jpg",
CURLFORM_END);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
// curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
//
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
res = curl_easy_perform(curl);
if (res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
curl_easy_cleanup(curl);
}
}
基于ftp协议的
url直接传文件路径,比如ftp://server.name/subdir/image.jpg
struct TmpStream {
void *ptr;
size_t last_num;
};
static size_t read_callback(void *ptr, size_t size, size_t nmemb, TmpStream *stream) {
if (stream->last_num <= 0)
return 0;
size_t retcode = size * nmemb;
retcode = MIN(retcode, stream->last_num);
memcpy(ptr, stream->ptr, retcode);
stream->last_num -= retcode;
// curl_off_t nread = (curl_off_t) retcode;
// fprintf(stderr, " We read %" CURL_FORMAT_CURL_OFF_T
// " bytes from file\n", nread);
return retcode;
}
void ftpUpload(const cv::Mat &img, const char *url) {
vector<uchar> vec_Img;
vector<int> vecCompression_params;
vecCompression_params.push_back(cv::IMWRITE_JPEG_QUALITY);
vecCompression_params.push_back(90);
imencode(".jpg", img, vec_Img, vecCompression_params);
// struct curl_slist *headerlist = nullptr;
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_USERPWD, "smc:123456");
/* we want to use our own write function */
// curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
/* we want to use our own read function */
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
/**create missing dir**/
curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L);
/* enable uploading */
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
/* specify target */
curl_easy_setopt(curl, CURLOPT_URL, url);
// /* pass in that last of FTP commands to run after the transfer */
// curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist);
/* now specify which file to upload */
TmpStream stream = {
vec_Img.data(), vec_Img.size()};
curl_easy_setopt(curl, CURLOPT_READDATA, &stream);
/* Set the size of the file to upload (optional). If you give a *_LARGE option you MUST make sure that the type of the passed-in argument is a curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must make sure that to pass in a type 'long' argument. */
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
(curl_off_t) vec_Img.size());
/* Now run off and do what you have been told! */
res = curl_easy_perform(curl);
/* Check for errors */
if (res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
/* clean up the FTP commands list */
// curl_slist_free_all(headerlist);
/* always cleanup */
curl_easy_cleanup(curl);
}
}
边栏推荐
- Win7怎么干净启动?如何只加载基本服务启动Win7系统
- 刷卡芯片CI520可直接PIN对PIN替换CV520支持SPI通讯接口
- Publish module to NPM should be how to operate?Solutions to problems and mistake
- How to add a one-key shutdown option to the right-click menu in Windows 11
- PyTorch⑩---卷积神经网络_一个小的神经网络搭建
- Binder ServiceManager解析
- PyTorch(13)---优化器_随机梯度下降法
- FP6293电池升压5V-12V大电流2APWM模式升压方案
- 针对多轮推理分类问题的软标签构造方法
- 文本匹配任务
猜你喜欢
随机推荐
PyTorch(11)---卷积神经网络_一个小的神经网络搭建model
FP7195转模拟调光技术解决智能家居调光频闪和电感噪音的原理
13.56MHZ刷卡芯片CI521兼容cv520/ci520支持A卡B卡MIFARE协议
TypeScript 快速进阶
FP7128内置MOS降压恒流调光深度0.01%高辉共阳调光方案
Win11电脑一段时间不操作就断网怎么解决
PyTorch②---transforms结构及用法、常见的Transforms
FP6296锂电池升压 5V9V12V内置 MOS 大功率方案原理图
Mysql connection error solution
Do Windows 10 computers need antivirus software installed?
将SSE指令转换为ARM NEON指令
没学好统计学的下场
2022TI杯D题混沌信号产生实验装置
对疫情期间量化策略表现的看法
STL容器自定义内存分配器
Win10电脑不能读取U盘怎么办?不识别U盘怎么解决?
PyTorch①---加载数据、tensorboard的使用
How to add a one-key shutdown option to the right-click menu in Windows 11
Actual combat Meituan Nuxt +Vue family bucket, server-side rendering, mailbox verification, passport authentication service, map API reference, mongodb, redis and other technical points
arm push/pop/b/bl汇编指令