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)
相关推荐
木头程序员1 分钟前
前端(包含HTML/JavaScript/DOM/BOM/jQuery)基础-暴力复习篇
开发语言·前端·javascript·ecmascript·es6·jquery·html5
Jayden_Ruan6 分钟前
C++分解质因数
数据结构·c++·算法
Data_agent12 分钟前
Cocbuy 模式淘宝 / 1688 代购系统(欧美市场)搭建指南
开发语言·python
lsx20240621 分钟前
《Foundation 下拉菜单》
开发语言
期待のcode25 分钟前
认识Java虚拟机
java·开发语言·jvm
微露清风28 分钟前
系统性学习C++-第二十讲-哈希表实现
c++·学习·散列表
raining_peidx29 分钟前
xxljob源码
java·开发语言
肥猪猪爸30 分钟前
双重检查锁(DCL)与 volatile 的关键作用
java·开发语言·单例模式
yaoxin52112338 分钟前
289. Java Stream API - 从字符串的字符创建 Stream
java·开发语言
清 澜42 分钟前
c++高频知识点总结 第 1 章:语言基础与预处理
c++·人工智能·面试