ImageUtility.h
#pragma once
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
class ImageUtility
{
public:
ImageUtility(void);
~ImageUtility(void);
// 实现cv::Mat 结构到 CImage结构的转化
void MatToCImage(Mat& mat, CImage& cImage);
// CImage结构到Mat结构的转化
void CImageToMat(CImage& cImage, Mat& mat);
// VS默认工程是Unicode编码(宽字节),有时需要ANSI,即单字节,实现宽到单的转化
string CString2StdString(const CString& cstr);
// 显示图像到指定窗口
void DisplayImage(CWnd* m_pMyWnd, const CImage& image);
// 格式转换,AWX云图转到可以显示的opencv支持的格式
Mat AWX2Mat(CString filePath);
void DisplayImageEx(CWnd* pWnd, const CImage& image);
};
ImageUtility.cpp
#include "ImageUtility.h"
ImageUtility::ImageUtility(void)
{
}
ImageUtility::~ImageUtility(void)
{
}
// 实现cv::Mat 结构到 CImage结构的转化
void ImageUtility::MatToCImage(Mat& mat, CImage& cImage)
{
int width = mat.cols;
int height = mat.rows;
int channels = mat.channels();
cImage.Destroy();//这一步是防止重复利用造成内存问题
cImage.Create(width, height, 8 * channels);
uchar* ps;
uchar* pimg = (uchar*)cImage.GetBits(); //获取CImage的像素存贮区的指针
int step = cImage.GetPitch();//每行的字节数,注意这个返回值有正有负
// 如果是1个通道的图像(灰度图像) DIB格式才需要对调色板设置
// CImage中内置了调色板,我们要对他进行赋值:
if (1 == channels)
{
RGBQUAD* ColorTable;
int MaxColors = 256;
//这里可以通过CI.GetMaxColorTableEntries()得到大小(如果你是CI.Load读入图像的话)
ColorTable = new RGBQUAD[MaxColors];
cImage.GetColorTable(0, MaxColors, ColorTable);//这里是取得指针
for (int i = 0; i<MaxColors; i++)
{
ColorTable[i].rgbBlue = (BYTE)i;
//BYTE和uchar一回事,但MFC中都用它
ColorTable[i].rgbGreen = (BYTE)i;
ColorTable[i].rgbRed = (BYTE)i;
}
cImage.SetColorTable(0, MaxColors, ColorTable);
delete[]ColorTable;
}
for (int i = 0; i < height; i++)
{
ps = mat.ptr<uchar>(i);
for (int j = 0; j < width; j++)
{
if (1 == channels)
{
*(pimg + i*step + j) = ps[j];
//*(pimg + i*step + j) = 105;
}
else if (3 == channels)
{
*(pimg + i*step + j * 3) = ps[j * 3];
*(pimg + i*step + j * 3 + 1) = ps[j * 3 + 1];
*(pimg + i*step + j * 3 + 2) = ps[j * 3 + 2];
}
}
}
//string str = CString2StdString(_T("C:\\sample1020.bmp"));
//imwrite(str,mat);
//这句话就是用来测试cimage有没有被赋值
//cImage.Save(_T("C:\\sample1024.bmp"));
}
// CImage结构到Mat结构的转化
void ImageUtility::CImageToMat(CImage& cImage, Mat& mat)
{
}
// VS默认工程是Unicode编码(宽字节),有时需要ANSI,即单字节,实现宽到单的转化
string ImageUtility::CString2StdString(const CString& cstr)
{
CT2A str(cstr);
return string(str.m_psz);
}
// 显示图像到指定窗口
void ImageUtility::DisplayImage(CWnd* m_pMyWnd, const CImage& image)
{
CDC *m_pDC = m_pMyWnd->GetDC();//获取窗口所拥有的设备上下文,用于显示图像
m_pMyWnd->UpdateWindow();
CRect rc;
m_pMyWnd->GetWindowRect(&rc);
/*InvalidateRect(m_pMyWnd->m_hWnd,&rc,true);*/
int nwidth = rc.Width();
int nheight = rc.Height();
int fixed_width = min(image.GetWidth(), nwidth);
int fixed_height = min(image.GetHeight(), nheight);
double ratio_w = fixed_width / (double)image.GetWidth();
double ratio_h = fixed_height / (double)image.GetHeight();
double ratio = min(ratio_w, ratio_h);
int show_width = (int)(image.GetWidth() * ratio);
int show_height = (int)(image.GetHeight() * ratio);
int offsetx = (nwidth - show_width) / 2;
int offsety = (nheight - show_height) / 2;
::SetStretchBltMode(m_pDC->GetSafeHdc(), COLORONCOLOR);//设置位图的伸缩模式
image.StretchBlt(m_pDC->GetSafeHdc(), offsetx, offsety, show_width, show_height,
0, 0, image.GetWidth(), image.GetHeight(), SRCCOPY);
}
// 格式转换,AWX云图转到可以显示的opencv支持的格式
Mat ImageUtility::AWX2Mat(CString filePath)
{
CFile fp;
Mat mat;
fp.Open(filePath, CFile::modeRead);
ULONGLONG flength = fp.GetLength();
if (2475700 == flength)
{
mat.create(1300, 1900, CV_8UC1);
}
else if (1444803 == flength)
{
mat.create(1201, 1201, CV_8UC1);
}
LONGLONG size = mat.rows * mat.cols;
LONGLONG sizebuff = fp.Seek(-size, CFile::end);
uchar *pSource = new uchar[size];
fp.Read(pSource, size);
fp.Close();
for (int i = 0; i<mat.rows; i++)
{
uchar * ps = mat.ptr<uchar>(i);
for (int j = 0; j < mat.cols; j++)
{
ps[j] = *(pSource + i*mat.cols + j);
}
}
delete pSource;
return mat;
}
void ImageUtility::DisplayImageEx(CWnd* pWnd, const CImage& image)
{
CDC *m_pDC = pWnd->GetDC();//获取窗口所拥有的设备上下文,用于显示图像
pWnd->UpdateWindow();
CRect rc;
//客户区大小
//CRect rc1;
pWnd->GetWindowRect(&rc);
//ScreenToClient(&rc);
::SetStretchBltMode(m_pDC->GetSafeHdc(), COLORONCOLOR);//设置位图的伸缩模式
image.StretchBlt(m_pDC->GetSafeHdc(), 0, 0, rc.Width() - 1, rc.Height() - 1,
0, 0, image.GetWidth(), image.GetHeight(), SRCCOPY);
}