From 22e86402f7f085666fb2d304a987d46de71eca2c Mon Sep 17 00:00:00 2001 From: AlOa Date: Tue, 11 Apr 2023 09:44:54 +0200 Subject: [PATCH] Read image from memory buffer for simpleocv (#4557) --- src/simpleocv.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++++++ src/simpleocv.h | 2 ++ 2 files changed, 86 insertions(+) diff --git a/src/simpleocv.cpp b/src/simpleocv.cpp index 5270cc7e9..99b2e3c80 100644 --- a/src/simpleocv.cpp +++ b/src/simpleocv.cpp @@ -138,6 +138,90 @@ Mat imread(const std::string& path, int flags) return img; } +Mat imdecode(const std::vector& buf, int flags) +{ + int desired_channels = 0; + if (flags == IMREAD_UNCHANGED) + { + desired_channels = 0; + } + else if (flags == IMREAD_GRAYSCALE) + { + desired_channels = 1; + } + else if (flags == IMREAD_COLOR) + { + desired_channels = 3; + } + else + { + // unknown flags + return Mat(); + } + + int w; + int h; + int c; + unsigned char* pixeldata = stbi_load_from_memory(&buf.front(), buf.size(), &w, &h, &c, desired_channels); + if (!pixeldata) + { + // load failed + return Mat(); + } + + if (desired_channels) + { + c = desired_channels; + } + + // copy pixeldata to Mat + Mat img; + if (c == 1) + { + img.create(h, w, CV_8UC1); + } + else if (c == 3) + { + img.create(h, w, CV_8UC3); + } + else if (c == 4) + { + img.create(h, w, CV_8UC4); + } + else + { + // unexpected channels + stbi_image_free(pixeldata); + return Mat(); + } + + memcpy(img.data, pixeldata, w * h * c); + + stbi_image_free(pixeldata); + + // rgb to bgr + if (c == 3) + { + uchar* p = img.data; + for (int i = 0; i < w * h; i++) + { + std::swap(p[0], p[2]); + p += 3; + } + } + if (c == 4) + { + uchar* p = img.data; + for (int i = 0; i < w * h; i++) + { + std::swap(p[0], p[2]); + p += 4; + } + } + + return img; +} + bool imwrite(const std::string& path, const Mat& m, const std::vector& params) { const char* _ext = strrchr(path.c_str(), '.'); diff --git a/src/simpleocv.h b/src/simpleocv.h index 55ede15b7..54b22d9f9 100644 --- a/src/simpleocv.h +++ b/src/simpleocv.h @@ -448,6 +448,8 @@ enum ImreadModes NCNN_EXPORT Mat imread(const std::string& path, int flags = IMREAD_COLOR); +NCNN_EXPORT Mat imdecode(const std::vector& buf, int flags = IMREAD_COLOR); + enum ImwriteFlags { IMWRITE_JPEG_QUALITY = 1