OpenCV Mat 转 ATL CImage

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);
}



  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值