16 # define STB_IMAGE_IMPLEMENTATION
17 # include "stb_image.h"
37 string name) : _name(std::move(name))
45 bool loadGrayscaleIntoAlpha)
48 assert(filename !=
"");
50 load(filename, flipVertical, loadGrayscaleIntoAlpha);
72 for (
auto color : colors)
75 (uchar)(color[1] * 255.0f),
76 (uchar)(color[2] * 255.0f));
86 for (
auto color : colors)
89 (uchar)(color[1] * 255.0f),
90 (uchar)(color[2] * 255.0f),
91 (uchar)(color[3] * 255.0f));
146 "CVImage::Allocate: Allocation failed",
184 Utils::exitMsg(
"SLProject",
"CVImage::bytesPerPixel: unknown pixel format", __LINE__, __FILE__);
200 uint bitsPerPixel = bpp * 8;
201 uint bpl = isContinuous ?
width * bpp : ((
width * bitsPerPixel + 31) / 32) * 4;
240 uchar* srcStart =
data;
242 if (srcPixelFormatGL == dstPixelFormatGL)
244 for (
int h = 0; h <
_cvMat.rows; ++h, srcStart += srcBPL, dstStart -= dstBPL)
246 memcpy(dstStart, srcStart, (
unsigned long)dstBPL);
251 if (srcPixelFormatGL ==
PF_bgra)
253 if (dstPixelFormatGL ==
PF_rgb)
255 for (
int h = 0; h <
_cvMat.rows; ++h, srcStart += srcBPL, dstStart -= dstBPL)
257 uchar* src = srcStart;
258 uchar* dst = dstStart;
259 for (
int w = 0; w <
_cvMat.cols - 1; ++w, dst += dstBPP, src += srcBPP)
267 else if (dstPixelFormatGL ==
PF_rgba)
269 for (
int h = 0; h <
_cvMat.rows; ++h, srcStart += srcBPL, dstStart -= dstBPL)
271 uchar* src = srcStart;
272 uchar* dst = dstStart;
273 for (
int w = 0; w <
_cvMat.cols - 1; ++w, dst += dstBPP, src += srcBPP)
283 else if (srcPixelFormatGL ==
PF_bgr || srcPixelFormatGL ==
PF_rgb)
285 if (dstPixelFormatGL ==
PF_rgb || dstPixelFormatGL ==
PF_bgr)
287 for (
int h = 0; h <
_cvMat.rows; ++h, srcStart += srcBPL, dstStart -= dstBPL)
289 uchar* src = srcStart;
290 uchar* dst = dstStart;
291 for (
int w = 0; w <
_cvMat.cols - 1; ++w, dst += dstBPP, src += srcBPP)
302 std::cout <<
"CVImage::load from memory: Pixel format conversion not allowed" << std::endl;
309 if (srcPixelFormatGL == dstPixelFormatGL)
315 uchar* dstStart =
_cvMat.data;
316 uchar* srcStart =
data;
318 if (srcPixelFormatGL ==
PF_bgra)
320 if (dstPixelFormatGL ==
PF_rgb)
322 for (
int h = 0; h <
_cvMat.rows - 1; ++h, srcStart += srcBPL, dstStart += dstBPL)
324 uchar* src = srcStart;
325 uchar* dst = dstStart;
326 for (
int w = 0; w <
_cvMat.cols - 1; ++w, dst += dstBPP, src += srcBPP)
334 else if (dstPixelFormatGL ==
PF_rgba)
336 for (
int h = 0; h <
_cvMat.rows - 1; ++h, srcStart += srcBPL, dstStart += dstBPL)
338 uchar* src = srcStart;
339 uchar* dst = dstStart;
340 for (
int w = 0; w <
_cvMat.cols - 1; ++w, dst += dstBPP, src += srcBPP)
350 else if (srcPixelFormatGL ==
PF_bgr || srcPixelFormatGL ==
PF_rgb)
352 if (dstPixelFormatGL ==
PF_rgb || dstPixelFormatGL ==
PF_bgr)
354 for (
int h = 0; h <
_cvMat.rows - 1; ++h, srcStart += srcBPL, dstStart += dstBPL)
356 uchar* src = srcStart;
357 uchar* dst = dstStart;
358 for (
int w = 0; w <
_cvMat.cols - 1; ++w, dst += dstBPP, src += srcBPP)
369 std::cout <<
"CVImage::load from memory: Pixel format conversion not allowed" << std::endl;
375 return needsTextureRebuild;
381 bool loadGrayscaleIntoAlpha)
392 #ifndef __EMSCRIPTEN__
393 _cvMat = cv::imread(filename, cv::ImreadModes::IMREAD_UNCHANGED);
397 unsigned char* encodedData = buffer.
data;
398 int size = (int)buffer.
size;
402 stbi_hdr_to_ldr_gamma(1.0f);
403 unsigned char*
data = stbi_load_from_memory(encodedData, size, &
width, &
height, &numChannels, 0);
411 string msg =
"CVImage.load: Loading failed: " + filename;
416 if (
_cvMat.depth() > CV_8U && ext !=
"hdr")
419 #ifndef __EMSCRIPTEN__
426 if (
_cvMat.type() == CV_8UC3)
428 else if (
_cvMat.type() == CV_8UC4)
455 for (
int y = 0; y < rgbaImg.rows; ++y)
457 uchar* dst = rgbaImg.ptr<uchar>(y);
458 uchar* src =
_cvMat.ptr<uchar>(y);
460 for (
int x = 0; x < rgbaImg.cols; ++x)
495 for (
int y = 0; y < rgbaImg.rows; ++y)
497 uchar* dst = rgbaImg.ptr<uchar>(y);
498 uchar* src =
_cvMat.ptr<uchar>(y);
500 for (
int x = 0; x < rgbaImg.cols; ++x)
502 uchar value = *src++;
526 case CV_8UC1:
return PF_red;
527 case CV_8UC2:
return PF_rg;
528 case CV_8UC3:
return PF_bgr;
538 case CV_8SC1:
Utils::exitMsg(
"SLProject",
"OpenCV image format CV_8SC1 not supported", __LINE__, __FILE__);
break;
539 case CV_8SC2:
Utils::exitMsg(
"SLProject",
"OpenCV image format CV_8SC2 not supported", __LINE__, __FILE__);
break;
540 case CV_8SC3:
Utils::exitMsg(
"SLProject",
"OpenCV image format CV_8SC3 not supported", __LINE__, __FILE__);
break;
541 case CV_8SC4:
Utils::exitMsg(
"SLProject",
"OpenCV image format CV_8SC4 not supported", __LINE__, __FILE__);
break;
542 case CV_16UC1:
Utils::exitMsg(
"SLProject",
"OpenCV image format CV_16UC1 not supported", __LINE__, __FILE__);
break;
543 case CV_16UC2:
Utils::exitMsg(
"SLProject",
"OpenCV image format CV_16UC2 not supported", __LINE__, __FILE__);
break;
544 case CV_16UC3:
Utils::exitMsg(
"SLProject",
"OpenCV image format CV_16UC3 not supported", __LINE__, __FILE__);
break;
545 case CV_16UC4:
Utils::exitMsg(
"SLProject",
"OpenCV image format CV_16UC4 not supported", __LINE__, __FILE__);
break;
546 case CV_16SC1:
Utils::exitMsg(
"SLProject",
"OpenCV image format CV_16SC1 not supported", __LINE__, __FILE__);
break;
547 case CV_16SC2:
Utils::exitMsg(
"SLProject",
"OpenCV image format CV_16SC2 not supported", __LINE__, __FILE__);
break;
548 case CV_16SC3:
Utils::exitMsg(
"SLProject",
"OpenCV image format CV_16SC3 not supported", __LINE__, __FILE__);
break;
549 case CV_16SC4:
Utils::exitMsg(
"SLProject",
"OpenCV image format CV_16SC4 not supported", __LINE__, __FILE__);
break;
550 case CV_32SC1:
Utils::exitMsg(
"SLProject",
"OpenCV image format CV_32SC1 not supported", __LINE__, __FILE__);
break;
551 case CV_32SC2:
Utils::exitMsg(
"SLProject",
"OpenCV image format CV_32SC2 not supported", __LINE__, __FILE__);
break;
552 case CV_32SC3:
Utils::exitMsg(
"SLProject",
"OpenCV image format CV_32SC3 not supported", __LINE__, __FILE__);
break;
553 case CV_32SC4:
Utils::exitMsg(
"SLProject",
"OpenCV image format CV_32SC4 not supported", __LINE__, __FILE__);
break;
555 "glPixelFormat2cvType: OpenCV image format not supported",
565 switch (pixelFormatGL)
570 case PF_rg:
return CV_8UC2;
571 case PF_rgb:
return CV_8UC3;
573 case PF_bgr:
return CV_8UC3;
585 string msg =
"glPixelFormat2cvType: OpenGL pixel format not supported: ";
596 switch (pixelFormatGL)
605 case PF_blue:
return "PF_blue";
607 case PF_red:
return "PF_red";
608 case PF_rg:
return "PF_rg";
609 case PF_rgb:
return "PF_rgb";
610 case PF_rgba:
return "PF_rgba";
611 case PF_bgr:
return "PF_bgr";
612 case PF_bgra:
return "PF_bgra";
619 case PF_r16f:
return "PF_r16f";
620 case PF_r32f:
return "PF_r32f";
626 default:
return string(
"Unknown pixel format");
638 const int compressionLevel,
640 const bool convertToRGB)
642 #ifndef __EMSCRIPTEN__
643 vector<int> compression_params;
644 compression_params.push_back(cv::IMWRITE_PNG_COMPRESSION);
645 compression_params.push_back(compressionLevel);
652 cv::flip(outImg, outImg, 0);
654 cv::cvtColor(outImg, outImg, cv::COLOR_BGR2RGB);
656 imwrite(filename, outImg, compression_params);
658 catch (std::runtime_error& ex)
660 string msg =
"CVImage.savePNG: Exception: ";
676 const int compressionLevel,
678 const bool convertBGR2RGB)
680 #ifndef __EMSCRIPTEN__
681 vector<int> compression_params;
682 compression_params.push_back(cv::IMWRITE_JPEG_QUALITY);
683 compression_params.push_back(cv::IMWRITE_JPEG_PROGRESSIVE);
684 compression_params.push_back(compressionLevel);
691 cv::flip(outImg, outImg, 0);
693 cv::cvtColor(outImg, outImg, cv::COLOR_BGR2RGB);
695 imwrite(filename, outImg, compression_params);
697 catch (std::runtime_error& ex)
699 string msg =
"CVImage.saveJPG: Exception: ";
757 uchar c =
_cvMat.at<uchar>(y, x);
777 default:
Utils::exitMsg(
"SLProject",
"CVImage::getPixeli: Unknown format!", __LINE__, __FILE__);
801 float X1 = 1.0f - fracX;
802 float Y1 = 1.0f - fracY;
804 float UR = fracX * Y1;
805 float LL = X1 * fracY;
806 float LR = fracX * fracY;
826 float r = UL * cUL[0] + LL * cLL[0] + UR * cUR[0] + LR * cLR[0];
827 float g = UL * cUL[1] + LL * cLL[1] + UR * cUR[1] + LR * cLR[1];
828 float b = UL * cUL[2] + LL * cLL[2] + UR * cUR[2] + LR * cLR[2];
847 (uchar)(color[1] * 255.0f),
848 (uchar)(color[2] * 255.0f));
852 (uchar)(color[1] * 255.0f),
853 (uchar)(color[0] * 255.0f));
857 (uchar)(color[1] * 255.0f),
858 (uchar)(color[2] * 255.0f),
859 (uchar)(color[3] * 255.0f));
863 (uchar)(color[1] * 255.0f),
864 (uchar)(color[0] * 255.0f),
865 (uchar)(color[3] * 255.0f));
872 R = (int)(color[0] * 255.0f);
873 G = (int)(color[1] * 255.0f);
874 B = (int)(color[2] * 255.0f);
875 _cvMat.at<uchar>(y, x) = (uchar)(((66 * R + 129 * G + 25 * B + 128) >> 8) + 16);
882 R = (int)(color[0] * 255.0f);
883 G = (int)(color[1] * 255.0f);
884 B = (int)(color[2] * 255.0f);
886 (uchar)(color[3] * 255.0f));
888 default:
Utils::exitMsg(
"SLProject",
"CVImage::setPixeli: Unknown format!", __LINE__, __FILE__);
902 (uchar)(color[1] * 255.0f + 0.5f),
903 (uchar)(color[2] * 255.0f + 0.5f));
916 (uchar)(color[1] * 255.0f + 0.5f),
917 (uchar)(color[2] * 255.0f + 0.5f));
930 (uchar)(color[1] * 255.0f + 0.5f),
931 (uchar)(color[2] * 255.0f + 0.5f),
932 (uchar)(color[3] * 255.0f + 0.5f));
945 cv::resize(
_cvMat, dst, dst.size(), 0, 0, cv::INTER_LINEAR);
995 default:
Utils::exitMsg(
"SLProject",
"CVImage::fill(r,g,b): Wrong format!", __LINE__, __FILE__);
1010 default:
Utils::exitMsg(
"SLProject",
"CVImage::fill(r,g,b,a): Wrong format!", __LINE__, __FILE__);
1017 float inWdivH = (float)
_cvMat.cols / (
float)
_cvMat.rows;
1019 float outWdivH = targetWdivH < 0.0f ? inWdivH : targetWdivH;
1030 if (inWdivH > outWdivH)
1034 cropW = (int)((
float)(
_cvMat.cols -
width) * 0.5f);
1037 wModulo4 =
width % 4;
1038 if (wModulo4 == 1)
width--;
1044 if (wModulo4 == 3)
width++;
1054 if (hModulo4 == 1)
height--;
1060 if (hModulo4 == 3)
height++;
1073 int numImgTypes = 35;
1074 int enum_ints[] = {CV_8U, CV_8UC1, CV_8UC2, CV_8UC3, CV_8UC4,
1075 CV_8S, CV_8SC1, CV_8SC2, CV_8SC3, CV_8SC4,
1076 CV_16U, CV_16UC1, CV_16UC2, CV_16UC3, CV_16UC4,
1077 CV_16S, CV_16SC1, CV_16SC2, CV_16SC3, CV_16SC4,
1078 CV_32S, CV_32SC1, CV_32SC2, CV_32SC3, CV_32SC4,
1079 CV_32F, CV_32FC1, CV_32FC2, CV_32FC3, CV_32FC4,
1080 CV_64F, CV_64FC1, CV_64FC2, CV_64FC3, CV_64FC4};
1082 string enum_strings[] = {
"CV_8U",
"CV_8UC1",
"CV_8UC2",
"CV_8UC3",
"CV_8UC4",
1083 "CV_8S",
"CV_8SC1",
"CV_8SC2",
"CV_8SC3",
"CV_8SC4",
1084 "CV_16U",
"CV_16UC1",
"CV_16UC2",
"CV_16UC3",
"CV_16UC4",
1085 "CV_16S",
"CV_16SC1",
"CV_16SC2",
"CV_16SC3",
"CV_16SC4",
1086 "CV_32S",
"CV_32SC1",
"CV_32SC2",
"CV_32SC3",
"CV_32SC4",
1087 "CV_32F",
"CV_32FC1",
"CV_32FC2",
"CV_32FC3",
"CV_32FC4",
1088 "CV_64F",
"CV_64FC1",
"CV_64FC2",
"CV_64FC3",
"CV_64FC4"};
1091 for (
int i = 0; i < numImgTypes; i++)
1093 if (cvMatTypeInt == enum_ints[i])
return enum_strings[i];
1095 return "unknown image type";
CVPixelFormatGL
Pixel format according to OpenGL pixel format defines.
vector< cv::Vec3f > CVVVec3f
vector< cv::Vec4f > CVVVec4f
OpenCV image class with the same interface as the former SLImage class.
uint _bytesPerPixel
Number of bytes per pixel.
void resize(int width, int height)
CVVec4f getPixelf(float x, float y)
void setPixeliRGB(int x, int y, CVVec3f color)
setPixeli sets the RGB pixel color at the integer pixel coordinate x, y
void fill(uchar r, uchar g, uchar b)
Fills the image with a certain rgb color.
void flipX()
Flip X coordinates used to make JPEGs from top-left to bottom-left images.
CVPixelFormatGL _format
OpenGL pixel format.
void setPixeliRGBA(int x, int y, CVVec4f color)
setPixeli sets the RGBA pixel color at the integer pixel coordinate x, y
void clearData()
Deletes all data and resets the image parameters.
uint _bytesPerLine
Number of bytes per line (stride)
static string typeString(int cvMatTypeInt)
Returns the cv::Mat.type()) as string.
void savePNG(const string &filename, int compressionLevel=6, bool flipY=true, bool convertBGR2RGB=true)
Save as PNG at a certain compression level (0-9)
static int glPixelFormat2cvType(CVPixelFormatGL pixelFormatGL)
Converts OpenGL pixel format to OpenCV mat type.
uint _bytesPerImage
Number of bytes per image.
static CVPixelFormatGL cvType2glPixelFormat(int cvType)
Converts OpenCV mat type to OpenGL pixel format.
CVVec4f getPixeli(int x, int y)
getPixeli returns the pixel color at the integer pixel coordinate x, y
void saveJPG(const string &filename, int compressionLevel=95, bool flipY=true, bool convertBGR2RGB=true)
Save as JPG at a certain compression level (0-100)
string _path
path on the filesystem
CVMat _cvMat
OpenCV mat matrix image type.
void convertTo(int cvDataType)
Converts the data type of the cvMat.
bool allocate(int width, int height, CVPixelFormatGL pixelFormatGL, bool isContinuous=true)
Memory allocation function.
void flipY()
Flip Y coordinates used to make JPEGs from top-left to bottom-left images.
void load(const string &filename, bool flipVertical=true, bool loadGrayscaleIntoAlpha=false)
Loads the image with the appropriate image loader.
void setPixeli(int x, int y, CVVec4f color)
setPixeli sets the RGB pixel color at the integer pixel coordinate x, y
uint _bytesInFile
Number of bytes in file.
void crop(float targetWdivH, int &cropW, int &cropH)
string _name
Image name (e.g. from the filename)
CVImage()
Default constructor.
SLIOBuffer readIntoBuffer(std::string path, SLIOStreamKind kind)
Reads an entire file into memory.
Utils provides utilities for string & file handling, logging and math functions.
unsigned int getFileSize(const string &pathfilename)
Returns the file size in bytes.
string getFileName(const string &pathFilename)
Returns the filename of path-filename string.
string getPath(const string &pathFilename)
Returns the path w. '\' of path-filename string.
void exitMsg(const char *tag, const char *msg, const int line, const char *file)
Terminates the application with a message. No leak checking.
string getFileExt(const string &filename)
Returns the file extension without dot in lower case.
Utility struct that holds a pointer and its length.
void deallocate()
Deallocates the data owned by the buffer.