154 lines
4.8 KiB
C++
154 lines
4.8 KiB
C++
//
|
|
// draw.cpp
|
|
// MNN
|
|
//
|
|
// Created by MNN on 2021/08/26.
|
|
// Copyright © 2018, Alibaba Group Holding Limited
|
|
//
|
|
|
|
#include <set>
|
|
#include "cv/types.hpp"
|
|
#include "cv/imgcodecs.hpp"
|
|
#include "cv/imgproc/color.hpp"
|
|
#include <MNN/expr/MathOp.hpp>
|
|
#include <MNN/expr/NeuralNetWorkOp.hpp>
|
|
#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<uint8_t>());
|
|
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<float>(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<uint8_t>* ctx = (std::vector<uint8_t>*)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<std::string> supportImages {
|
|
"jpg", "jpeg", "png", "bmp", /* "gif", "psd", "pic", "pnm", "hdr", "tga" */
|
|
};
|
|
return supportImages.find(getExt(filename)) != supportImages.end();
|
|
}
|
|
|
|
VARP imdecode(const std::vector<uint8_t>& 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<bool, std::vector<uint8_t>> imencode(std::string ext, VARP img, const std::vector<int>& params) {
|
|
VARP rgb = cvtColor(img, COLOR_BGR2RGB);
|
|
int height, width, channel;
|
|
getVARPSize(rgb, &height, &width, &channel);
|
|
ext = getExt(ext);
|
|
bool res = false;
|
|
std::vector<uint8_t> 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<uint8_t>(), quality);
|
|
}
|
|
if (ext == "png") {
|
|
res = stbi_write_png_to_func(writeFunc, (void*)&buf, width, height, channel, rgb->readMap<uint8_t>(), 0);
|
|
}
|
|
if (ext == "bmp") {
|
|
res = stbi_write_bmp_to_func(writeFunc, (void*)&buf, width, height, channel, rgb->readMap<uint8_t>());
|
|
}
|
|
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<int>& params) {
|
|
if (img->getInfo()->type != halide_type_of<uint8_t>()) {
|
|
img = _Cast<uint8_t>(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<uint8_t>(), quality);
|
|
}
|
|
if (ext == "png") {
|
|
return stbi_write_png(filename.c_str(), width, height, channel, img->readMap<uint8_t>(), 0);
|
|
}
|
|
if (ext == "bmp") {
|
|
return stbi_write_bmp(filename.c_str(), width, height, channel, img->readMap<uint8_t>());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
} // CV
|
|
} // MNN
|