c++使用http发送图像

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

为了方便 接收端使用的python

发送端 cpp

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

文件结构

account_dir-> httplib.h

media-> cat.png

CMakeLists.txt

first_cmake.cpp

run.sh

first_cmake.cpp 文件内容

cpp 复制代码
#include <iostream>
#include <opencv2/opencv.hpp>
#include "httplib.h"


int main()
{   

    // 使用imread函数读取图片,和Python用法类似
    // 读取的数据保存在Mat类型的变量image中,Mat是opencv中的图像数据结构,类似numpy中的ndarray
    cv::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;
        return 1;
        }

    std::cout << "图片高度: " << image.rows << "宽度: " << image.cols << std::endl;


    // 1. 创建HTTP客户端
    httplib::Client client("192.168.11.100", 25565);


    // 2. 检查客户端是否创建成功
    if (!client.is_valid()) {
        std::cout << "无法连接到 192.168.11.100:25565" << std::endl;
        return 1;
    }
		// 循环10次是为了测试
    for (int i=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::string image_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); 

    return 0;
}

CMakeLists.txt 文件内容

bash 复制代码
# 最低版本要求
cmake_minimum_required(VERSION 3.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 文件内容

bash 复制代码
rm -r build
mkdir build
cd build
cmake ..
cd ../
cmake --build build
./build/first_cmake

接收端 python

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

python 复制代码
from flask import Flask, request, jsonify
import cv2
import numpy as np
import os

app = Flask(__name__)

@app.route('/upload', methods=['POST'])
def receive_image():
    while True:
        """
        标准图像接收接口
        """
        try:
            # 1. 获取原始图像字节数据
            image_bytes = request.data
            
            print(f"收到数据大小: {len(image_bytes)} 字节")
            
            # 2. 转换为OpenCV格式
            nparr = np.frombuffer(image_bytes, np.uint8)
            img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
            
            if img is None:
                print("错误: 无法解码图像数据")
                return jsonify({'status': 'error', 'message': '无法解码图像'}), 400
            
            # 3. 获取图像信息
            height, width = img.shape[:2]
            channels = img.shape[2] if len(img.shape) > 2 else 1
            
            print(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. 返回响应
            return jsonify({
                'status': 'success',
                'width': width,
                'height': height,
                'channels': channels,
                'size_bytes': len(image_bytes)
            })
            
        except Exception as e:
            print(f"服务器错误: {str(e)}")
            return jsonify({'status': 'error', 'message': str(e)}), 500

if __name__ == '__main__':
    print("服务器启动在 http://0.0.0.0:25565")
    print("等待接收图像...")
    app.run(host='0.0.0.0', port=25565, debug=True)
相关推荐
不爱吃糖的程序媛2 小时前
OpenHarmony PC 第三方 C/C++ 库适配完整指南
c语言·c++·harmonyos
雪域迷影2 小时前
nlohmann::json库对象和json结构体转换的新方式
c++·json·nlohmann_json库
木千2 小时前
Qt中关于QLineEdit控件的editingFinished信号执行两次的处理方式
开发语言·qt
浔川python社2 小时前
C++小程序编写系列(2)
c++·算法·图论
山风wind2 小时前
设计模式-单例模式详解
开发语言·javascript·ecmascript
未来之窗软件服务2 小时前
幽冥大陆(五十三)人工智能开发语言选型指南——东方仙盟筑基期
开发语言·人工智能·仙盟创梦ide·东方仙盟
后端小张2 小时前
【JAVA 进阶】深入理解Sentinel:分布式系统的流量守卫者
java·开发语言·spring boot·后端·spring·spring cloud·sentinel
fengche19152 小时前
【无标题】keilC编译器版本问题,低版本
c++
cheems95272 小时前
[JavaEE] CAS 介绍
java·开发语言·java-ee