当前位置: 首页 > news >正文

c++使用http发送图像

写这个是为了解决vscode远程服务时,无法实时显示正在处理的图像,想知道就得保存后才能看。现在是基础示例,你可以根据自己的要求封装。

为了方便 接收端使用的python

发送端 cpp

这里面为了方便快,使用了缩放和压缩

文件结构
account_dir-> httplib.h
media-> cat.png
CMakeLists.txt
first_cmake.cpp
run.sh

first_cmake.cpp 文件内容

#include<iostream>#include<opencv2/opencv.hpp>#include"httplib.h"intmain(){// 使用imread函数读取图片,和Python用法类似// 读取的数据保存在Mat类型的变量image中,Mat是opencv中的图像数据结构,类似numpy中的ndarraycv::Mat image=cv::imread("./media/cat.png");// 在终端输入命令: ./build/open_domo ./media/cat.jpg// cv::Mat image = cv::imread("./media/cat.jpg", 0); // 0代表 直接加载灰度图// cv::Mat image = cv::imread(argv[1]);cv::Mat resize;cv::resize(image,resize,cv::Size(640,640));// 判断图像是否读取成功,返回true表示失败if(resize.empty())// 使用!image.data也可以判断{std::cout<<"无法读取图片"<<std::endl;return1;}std::cout<<"图片高度: "<<image.rows<<"宽度: "<<image.cols<<std::endl;// 1. 创建HTTP客户端httplib::Clientclient("192.168.11.100",25565);// 2. 检查客户端是否创建成功if(!client.is_valid()){std::cout<<"无法连接到 192.168.11.100:25565"<<std::endl;return1;}// 循环10次是为了测试for(inti=1;i<=10;i++){std::vector<uchar>buffer;// PNG压缩级别:0=无压缩(文件大),9=最大压缩(文件小,编码慢)std::vector<int>png_params={cv::IMWRITE_PNG_COMPRESSION,9};// 无压缩cv::imencode(".png",resize,buffer,png_params);std::stringimage_data(buffer.begin(),buffer.end());// // 编码为二进制// std::vector<uchar> buffer;// cv::imencode(".png", image, buffer);// // 转为字符串// std::string image_data(buffer.begin(), buffer.end());// // 4. 发送POST请求// // "image/jpeg":这是JPEG图像格式// // "image/png":这是PNG图像格式// // "text/plain":这是纯文本// // "application/json":这是JSON数据httplib::Result result=client.Post("/upload",image_data,"image/png");// auto res = client.Post("/upload", image_data, "image/jpeg");// 检查请求结果// if (result) {// // 请求成功,检查状态码// if (result->status == 200) {// std::cout << "请求成功: " << result->body << std::endl;// } else {// std::cout << "服务器返回错误: " << result->status << std::endl;// std::cout << "响应内容: " << result->body << std::endl;// }// } else {// // 请求失败// auto err = result.error();// std::cout << "HTTP请求失败: " << httplib::to_string(err) << std::endl;// }}//标志位// std::cout << "flags:" << image.flags << std::endl;//图像尺寸// std::cout << "size:" << image.size << std::endl;// 图像通道数//std::cout << "channels" << input_image.channels() << std::endl;//维度// std::cout << "dims:" << image.dims << std::endl;// // 保存图像// cv::imwrite("./gray_image.jpg", image);// imshow显示图像// cv::imshow("opencv demo", image);// 等待按键// cv::waitKey(0);return0;}

CMakeLists.txt 文件内容

# 最低版本要求cmake_minimum_required(VERSION3.10)# 项目信息project(demo_opencv)# 查找opencv库(REQUIRED表示找不到就终止编译)find_package(OpenCV REQUIRED)# 给自己写个提示 也方便查找报错原因# 关键修复:变量名是 OpenCV_FOUND(大小写敏感)if(OpenCV_FOUND)# 找到后打印一些信息message(STATUS"openCV library status:")message(STATUS" version:${OpenCV_VERSION}")# 版本message(STATUS" libraries:${OpenCV_LIBS}")# 修复:库名称应该用 OpenCV_LIBS(你之前写的是 INCLUDE_DIRS)message(STATUS" include path:${OpenCV_INCLUDE_DIRS}")# 库的头文件路径else()# 找不到message(STATUS"openCV library status: !!!!!! not found !!!!!!!")endif()# 添加可执行文件add_executable(first_cmake"./first_cmake.cpp")# 添加头文件target_include_directories(first_cmake PRIVATE${OpenCV_INCLUDE_DIRS}"${CMAKE_CURRENT_SOURCE_DIR}/account_dir"# 添加你的头文件所在目录)# 添加链接target_link_libraries(first_cmake PRIVATE${OpenCV_LIBS})

run.sh 文件内容

rm-r buildmkdirbuildcdbuild cmake..cd../ cmake --build build ./build/first_cmake

接收端 python

图像关闭时,鼠标点击叉号,不要使用按键。

fromflaskimportFlask,request,jsonifyimportcv2importnumpyasnpimportos app=Flask(__name__)@app.route('/upload',methods=['POST'])defreceive_image():whileTrue:""" 标准图像接收接口 """try:# 1. 获取原始图像字节数据image_bytes=request.dataprint(f"收到数据大小:{len(image_bytes)}字节")# 2. 转换为OpenCV格式nparr=np.frombuffer(image_bytes,np.uint8)img=cv2.imdecode(nparr,cv2.IMREAD_COLOR)ifimgisNone:print("错误: 无法解码图像数据")returnjsonify({'status':'error','message':'无法解码图像'}),400# 3. 获取图像信息height,width=img.shape[:2]channels=img.shape[2]iflen(img.shape)>2else1print(f"解码成功:{width}x{height}, 通道数:{channels}")print(f"图像数据类型:{img.dtype}")print(f"图像最大值:{img.max()}, 最小值:{img.min()}")# 4. 保存图像# 保存原始接收到的图像# cv2.imwrite('received_image.png', img)# print(f"图像已保存为: received_image.png")# 调整宽高(再次运行也只会加载你调整后的宽高)cv2.namedWindow("1",cv2.WINDOW_NORMAL)cv2.imshow("1",img)# 必要参数:名字和变量名cv2.waitKey(0)# 括号中0=任意键终止,单位为毫秒级别# 6. 返回响应returnjsonify({'status':'success','width':width,'height':height,'channels':channels,'size_bytes':len(image_bytes)})exceptExceptionase:print(f"服务器错误:{str(e)}")returnjsonify({'status':'error','message':str(e)}),500if__name__=='__main__':print("服务器启动在 http://0.0.0.0:25565")print("等待接收图像...")app.run(host='0.0.0.0',port=25565,debug=True)
http://www.cnnetsun.cn/news/126447.html

相关文章:

  • MCP DP-420图Agent备份避坑指南(20年经验总结的6大雷区)
  • MCP Azure量子服务配置陷阱曝光:如何避免4类常见部署失败?
  • “中国甜糯玉米之乡”香飘荆楚 五寨区域公用品牌亮相武汉粮油展
  • 为什么90%的PL-600项目初期都搞错了Agent权限分级?
  • 你还在盲目刷题?:这9类MCP量子认证高频模拟题才是关键
  • (MCP续证终极攻略):从零开始30天拿证的完整学习计划
  • 2025年最新AI编程工具权威评测:这九款利器让编程效率倍增
  • 云安全监控告警失效?,深入解析AZ-500 Agent日志采集全流程
  • 如何通过MCP SC-400实现GDPR合规?1个架构师的私密实践笔记
  • Ramile:智能软件著作权代码提取神器,告别手动整理的烦恼!
  • 1.45亿,合肥市低空经济基础设施项目
  • Chrome垂直标签页:重新定义浏览器标签管理新标准
  • 一站式直播聚合神器:5分钟学会用Simple Live统一所有平台直播
  • MCP Azure量子服务配置实战指南(从零到生产级部署)
  • 终极指南:如何用GBT7714样式库一键搞定国标引用格式
  • MCP AI-102模型部署全解析(专家级配置方案曝光)
  • 霍尔电流传感器使用年限多久,到期后必须更换么?
  • 亲测!山东好用AI公司实践案例分享
  • Zotero文献格式修复:告别混乱标题的专业解决方案
  • 12、网络间谍软件、犯罪与防范全解析
  • MCP DP-420图Agent查询性能提升:90%工程师忽略的3个关键优化点
  • Origin Private File System (OPFS):Web 上的高性能原生文件系统访问
  • 终极IDM使用指南:解锁完整版功能
  • PDF翻译效率革命:智能解析与格式无损转换技术深度解析
  • 5个必学技巧:在MacBook Pro上极致发挥AI图像放大潜力
  • springboot基于Java Web的虚拟实验室设备租赁管理系统的设计与实现_x69d6kd5
  • springboot基于SSM框架的家庭个人收支管理系统_za55mo75
  • Diff Checker:高效文件差异对比工具完整指南
  • KlipperScreen终极部署指南:从零打造专业级3D打印机触控界面
  • 数智化不动产登记与地籍信息化建设方案