寻求mongocxx向MongoDB插入二进制图片的可用示例(基于OpenCV)
基于OpenCV与mongocxx实现图片二进制插入MongoDB的完整示例
我懂这种找不到合适示例的头疼——之前我在做计算机视觉项目的时候也遇到过类似需求,折腾了好一阵才搞定。下面给你一个完整的可运行示例,涵盖从OpenCV读取图片、转成二进制流,到用mongocxx插入MongoDB的全流程,还附带读取验证的代码。
前置准备
确保你的环境已经配置好:
- 安装并链接好 mongocxx 驱动(建议用v3.6+版本)
- 安装好 OpenCV 4.x(兼容3.x版本,代码微调即可)
- 本地或远程MongoDB服务正常运行
完整代码示例
#include <iostream> #include <vector> #include <mongocxx/client.hpp> #include <mongocxx/instance.hpp> #include <mongocxx/uri.hpp> #include <bsoncxx/builder/stream/document.hpp> #include <bsoncxx/types.hpp> #include <opencv2/opencv.hpp> using namespace mongocxx; using namespace bsoncxx::builder::stream; using namespace cv; int main() { // 初始化mongocxx实例 instance inst{}; // 连接MongoDB(替换成你的连接URI) uri mongodb_uri("mongodb://localhost:27017"); client conn(mongodb_uri); // 获取数据库和集合 auto db = conn["image_db"]; auto coll = db["images"]; // -------------------------- // 步骤1:用OpenCV读取图片 // -------------------------- Mat image = imread("test.jpg", IMREAD_COLOR); if (image.empty()) { std::cerr << "Failed to read image!" << std::endl; return -1; } // -------------------------- // 步骤2:将Mat转换为二进制流 // -------------------------- std::vector<uchar> image_buffer; // 把图片编码成JPEG格式(也可以用PNG:IMWRITE_PNG_COMPRESSION) imencode(".jpg", image, image_buffer); // -------------------------- // 步骤3:构造BSON文档,包含二进制和其他元数据 // -------------------------- bsoncxx::types::b_binary binary_data{ bsoncxx::binary_sub_type::k_binary, // 二进制类型标记 static_cast<uint32_t>(image_buffer.size()), // 二进制数据长度 image_buffer.data() // 二进制数据指针 }; auto doc = document{} << "filename" << "test.jpg" << "width" << image.cols << "height" << image.rows << "channels" << image.channels() << "image_data" << binary_data << finalize; // -------------------------- // 步骤4:插入文档到MongoDB // -------------------------- auto result = coll.insert_one(doc.view()); if (result) { std::cout << "Image inserted successfully! Document ID: " << result->inserted_id() << std::endl; } else { std::cerr << "Failed to insert image!" << std::endl; return -1; } // -------------------------- // 可选:读取插入的文档,验证是否成功 // -------------------------- auto found_doc = coll.find_one(document{} << "filename" << "test.jpg" << finalize); if (found_doc) { // 提取二进制数据 auto binary = found_doc->view()["image_data"].get_binary(); std::vector<uchar> retrieved_buffer(binary.bytes, binary.bytes + binary.size); // 解码回Mat Mat retrieved_image = imdecode(retrieved_buffer, IMREAD_COLOR); if (!retrieved_image.empty()) { std::cout << "Image retrieved successfully! Displaying..." << std::endl; imshow("Retrieved Image", retrieved_image); waitKey(0); destroyAllWindows(); } } return 0; }
关键细节解释
- OpenCV图片转二进制:用
imencode把Mat对象编码成指定格式的字节流,这样能保证图片数据的完整性,也方便后续解码还原。你可以根据需求替换编码格式(比如.png)。 - mongocxx二进制类型:用
bsoncxx::types::b_binary来封装二进制数据,注意binary_sub_type选k_binary即可(这是通用二进制类型,适合存储图片这类数据)。 - 元数据存储:建议同时存储图片的文件名、尺寸、通道数等元数据,后续读取或处理时会很方便。
- 编译链接注意事项:编译时要链接mongocxx和OpenCV的库,比如g++命令:
g++ -std=c++17 image_insert.cpp -o image_insert $(pkg-config --cflags --libs mongocxx opencv4)
常见问题排查
- 如果插入后二进制数据为空:检查
imencode是否成功,确保图片路径正确,且OpenCV支持该图片格式。 - 如果读取后图片无法显示:确认
binary_sub_type和编码格式匹配,解码时用对应的IMREAD_*参数。
内容的提问来源于stack exchange,提问作者2adnielsenx xx
相关产品推荐
相关产品推荐

