// // draw.cpp // MNN // // Created by MNN on 2021/08/26. // Copyright © 2018, Alibaba Group Holding Limited // #include #include "cv/types.hpp" #include "cv/imgcodecs.hpp" #include "cv/imgproc/color.hpp" #include #include #define STB_IMAGE_IMPLEMENTATION #define STBI_NO_THREAD_LOCALS #define STBI_ONLY_JPEG #define STBI_ONLY_PNG #define STBI_ONLY_BMP #define STB_IMAGE_STATIC #define STB_IMAGE_WRITE_STATIC #include "stb_image.h" #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image_write.h" namespace MNN { namespace CV { // helper functions static VARP buildImgVARP(uint8_t* img, int height, int width, int channel, int flags) { auto rgb = _Const(img, {height, width, channel}, NHWC, halide_type_of()); free(img); VARP res; switch (flags) { case IMREAD_COLOR: res = cvtColor(rgb, COLOR_RGB2BGR); break; case IMREAD_GRAYSCALE: res = cvtColor(rgb, COLOR_RGB2GRAY); break; case IMREAD_ANYDEPTH: res = _Cast(rgb); break; default: MNN_ERROR("Don't support imread flags!"); return rgb; } return res; } static void writeFunc(void *context, void *data, int size) { std::vector* ctx = (std::vector*)context; ctx->insert(ctx->end(), (uint8_t*)data, (uint8_t*)data + size); } static std::string getExt(std::string name) { auto ext = name.substr(name.rfind('.') + 1, -1); std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); return ext; } // helper functions bool haveImageReader(const std::string& filename) { int width, height, channel; return stbi_info(filename.c_str(), &width, &height, &channel); } bool haveImageWriter(const std::string& filename) { static const std::set supportImages { "jpg", "jpeg", "png", "bmp", /* "gif", "psd", "pic", "pnm", "hdr", "tga" */ }; return supportImages.find(getExt(filename)) != supportImages.end(); } VARP imdecode(const std::vector& buf, int flags) { int width, height, channel; auto img = stbi_load_from_memory(buf.data(), buf.size(), &width, &height, &channel, 3); if (nullptr == img) { MNN_ERROR("Can't decode\n"); return nullptr; } return buildImgVARP(img, height, width, 3, flags); } std::pair> imencode(std::string ext, VARP img, const std::vector& params) { VARP rgb = cvtColor(img, COLOR_BGR2RGB); int height, width, channel; getVARPSize(rgb, &height, &width, &channel); ext = getExt(ext); bool res = false; std::vector buf; if (ext == "jpg" || "jpeg") { int quality = 95; for (size_t i = 0; i < params.size(); i += 2) { if (params[i] == IMWRITE_JPEG_QUALITY) { quality = params[i + 1]; break; } } res = stbi_write_jpg_to_func(writeFunc, (void*)&buf, width, height, channel, rgb->readMap(), quality); } if (ext == "png") { res = stbi_write_png_to_func(writeFunc, (void*)&buf, width, height, channel, rgb->readMap(), 0); } if (ext == "bmp") { res = stbi_write_bmp_to_func(writeFunc, (void*)&buf, width, height, channel, rgb->readMap()); } return { res, buf }; } VARP imread(const std::string& filename, int flags) { int width, height, channel; auto img = stbi_load(filename.c_str(), &width, &height, &channel, 3); if (nullptr == img) { MNN_ERROR("Can't open %s\n", filename.c_str()); return nullptr; } return buildImgVARP(img, height, width, 3, flags); } bool imwrite(const std::string& filename, VARP img, const std::vector& params) { if (img->getInfo()->type != halide_type_of()) { img = _Cast(img); } int height, width, channel; getVARPSize(img, &height, &width, &channel); if (channel == 3) { img = cvtColor(img, COLOR_BGR2RGB); } else { MNN_ERROR("MNN cv imwrite just support RGB/BGR format."); } auto ext = getExt(filename); if (ext == "jpg" || ext == "jpeg") { int quality = 95; for (size_t i = 0; i < params.size(); i += 2) { if (params[i] == IMWRITE_JPEG_QUALITY) { quality = params[i + 1]; break; } } return stbi_write_jpg(filename.c_str(), width, height, channel, img->readMap(), quality); } if (ext == "png") { return stbi_write_png(filename.c_str(), width, height, channel, img->readMap(), 0); } if (ext == "bmp") { return stbi_write_bmp(filename.c_str(), width, height, channel, img->readMap()); } return false; } } // CV } // MNN