#pragma once #include "opencv2/imgproc/imgproc.hpp" using namespace System; using namespace System::Drawing; using namespace System::Drawing::Imaging; using namespace System::IO; namespace openalprnet { private ref class BitmapMat : IDisposable { private: cv::Mat* m_bitmap; bool m_disposed; public: BitmapMat(array^ byteArray); BitmapMat(Bitmap^ bitmap); BitmapMat(MemoryStream^ memoryStream); BitmapMat(String^ filename); ~BitmapMat() { if (this->m_disposed) { return; } this->!BitmapMat(); this->m_disposed = true; } !BitmapMat() { delete[] m_bitmap->data; } property cv::Mat Value { cv::Mat get() { cv::Mat value = this->m_bitmap->clone(); return value; } } private: static cv::Mat* BitmapToMat(Bitmap^ bitmap) { int channels = 0; switch (bitmap->PixelFormat) { case PixelFormat::Format8bppIndexed: case PixelFormat::Format1bppIndexed: channels = 1; break; case PixelFormat::Format24bppRgb: channels = 3; break; case PixelFormat::Format32bppRgb: case PixelFormat::Format32bppArgb: case PixelFormat::Format32bppPArgb: channels = 4; break; default: throw gcnew NotSupportedException(bitmap->PixelFormat.ToString()); } BitmapData^ bitmapData = bitmap->LockBits( System::Drawing::Rectangle(0, 0, bitmap->Width, bitmap->Height), ImageLockMode::ReadOnly, bitmap->PixelFormat ); const int totalBytes = bitmap->Height * bitmapData->Stride; char *dst = new char[totalBytes]; ::memcpy(dst, bitmapData->Scan0.ToPointer(), totalBytes); cv::Mat* dstMat = new cv::Mat(cv::Size(bitmap->Width, bitmap->Height), CV_8UC(channels), dst); bitmap->UnlockBits(bitmapData); return dstMat; } static cv::Mat* MemoryStreamBitmapToMat(MemoryStream^ memoryStream) { Bitmap^ bitmap = gcnew Bitmap(memoryStream); cv::Mat* mat = BitmapToMat(bitmap); delete bitmap; return mat; } static cv::Mat* ByteArrayToMat(array^ byteArray) { MemoryStream^ ms = gcnew MemoryStream(byteArray); cv::Mat* mat = MemoryStreamBitmapToMat(ms); delete ms; return mat; } }; }