VC++ 图像格式转换(CImage、Mat、Gdiplus::Bitmap、IplImage)

封装类声明(CImageMat.h):

// CImageMat.h
class CImageMat
{
public:
	/*MatToCImage
	*简介:
	*	OpenCV的Mat转ATL/MFC的CImage,仅支持单通道灰度或三通道彩色
	*参数:
	*	mat:OpenCV的Mat
	*	cimage:ATL/MFC的CImage
	*/
	static void MatToCImage(Mat& mat, CImage& cimage);


	/*CImageToMat
	*简介:
	*	ATL/MFC的CImage转OpenCV的Mat,仅支持单通道灰度或三通道彩色
	*参数:
	*	cimage:ATL/MFC的CImage
	*	mat:OpenCV的Mat
	*/
	static void CImageToMat(CImage& cimage, Mat& mat);

	static void CGdiImageToMat(Gdiplus::Bitmap* image, Mat& mat);
	static Gdiplus::Bitmap* MatToCGdiImage(Mat& mat);

	static void BitmapToIplImage(Gdiplus::Bitmap* pBitmap, IplImage* &pIplImg);
	static void IplImageToBitmap(IplImage* pIplImg, Gdiplus::Bitmap* &pBitmap);
};

源码实现(CImageMat.cpp):

#include "stdafx.h"
#include "ImageMat.h"

void CrossImage(CImage &img)  //对像素进行转换
{
	for (int i = 0; i < img.GetWidth(); i++)
	{
		for (int j = 0; j < img.GetHeight(); j++)
		{
			UCHAR *cr = (UCHAR*)img.GetPixelAddress(i, j);
			cr[0] = cr[0] * cr[3] / 255;
			cr[1] = cr[1] * cr[3] / 255;
			cr[2] = cr[2] * cr[3] / 255;
		}
	}
}

void CImageMat::MatToCImage(Mat& mat, CImage& cimage)
{
	if (0 == mat.total())
		return;

	int nChannels = mat.channels();
	if ((1 != nChannels) && (3 != nChannels))
		return;
	
	int nWidth = mat.cols;
	int nHeight = mat.rows;

	//重建cimage
	cimage.Destroy();
	cimage.Create(nWidth, nHeight, 8 * nChannels);

	//拷贝数据
	uchar* pucRow;									//指向数据区的行指针
	uchar* pucImage = (uchar*)cimage.GetBits();		//指向数据区的指针
	int nStep = cimage.GetPitch();					//每行的字节数,注意这个返回值有正有负

	if (1 == nChannels)								//对于单通道的图像需要初始化调色板
	{
		RGBQUAD* rgbquadColorTable;
		int nMaxColors = 256;
		rgbquadColorTable = new RGBQUAD[nMaxColors];
		cimage.GetColorTable(0, nMaxColors, rgbquadColorTable);
		for (int nColor = 0; nColor < nMaxColors; nColor++)
		{
			rgbquadColorTable[nColor].rgbBlue = (uchar)nColor;
			rgbquadColorTable[nColor].rgbGreen = (uchar)nColor;
			rgbquadColorTable[nColor].rgbRed = (uchar)nColor;
		}
		cimage.SetColorTable(0, nMaxColors, rgbquadColorTable);
		delete[]rgbquadColorTable;
	}


	for (int nRow = 0; nRow < nHeight; nRow++)
	{
		pucRow = (mat.ptr<uchar>(nRow));
		for (int nCol = 0; nCol < nWidth; nCol++)
		{
			if (1 == nChannels)
			{
				*(pucImage + nRow * nStep + nCol) = pucRow[nCol];
			}
			else if (3 == nChannels)
			{
				for (int nCha = 0; nCha < 3; nCha++)
				{
					*(pucImage + nRow * nStep + nCol * 3 + nCha) = pucRow[nCol * 3 + nCha];
				}
			}
		}
	}
}

void CImageMat::CImageToMat(CImage& cimage, Mat& mat)
{
	if (true == cimage.IsNull())
	{
		return;
	}


	int nChannels = cimage.GetBPP() / 8;
	if ((1 != nChannels) && (3 != nChannels))
	{
		return;
	}
	int nWidth = cimage.GetWidth();
	int nHeight = cimage.GetHeight();


	//重建mat
	if (1 == nChannels)
	{
		mat.create(nHeight, nWidth, CV_8UC1);
	}
	else if (3 == nChannels)
	{
		mat.create(nHeight, nWidth, CV_8UC3);
	}
	else if (4 == nChannels)
	{
		mat.create(nHeight, nWidth, CV_8UC4);
	}

	//拷贝数据
	uchar* pucRow;									//指向数据区的行指针
	uchar* pucImage = (uchar*)cimage.GetBits();		//指向数据区的指针
	int nStep = cimage.GetPitch();					//每行的字节数,注意这个返回值有正有负

	for (int nRow = 0; nRow < nHeight; nRow++)
	{
		pucRow = (mat.ptr<uchar>(nRow));
		for (int nCol = 0; nCol < nWidth; nCol++)
		{
			if (1 == nChannels)
			{
				pucRow[nCol] = *(pucImage + nRow * nStep + nCol);
			}
			else if (3 == nChannels || 4 == nChannels)
			{
				for (int nCha = 0; nCha < nChannels; nCha++)
				{
					pucRow[nCol * 3 + nCha] = *(pucImage + nRow * nStep + nCol * nChannels + nCha);
				}
			}
		}
	}
}

void CImageMat::CGdiImageToMat(Gdiplus::Bitmap *image, Mat& mat)
{
	Gdiplus::BitmapData source;
	Gdiplus::Rect rect(0, 0, image->GetWidth(), image->GetHeight());
	Gdiplus::Status status = image->LockBits(&rect, Gdiplus::ImageLockModeRead, image->GetPixelFormat(), &source);
	if (status != Gdiplus::Ok) {
		return ;
	}

	int nWidth = image->GetWidth();
	int nHeight = image->GetHeight();
	if (Gdiplus::IsAlphaPixelFormat((Gdiplus::PixelFormat)image->GetPixelFormat()))
		mat.create(nHeight, nWidth, CV_8UC4);
	else
		mat.create(nHeight, nWidth, CV_8UC3);

	BYTE *destination = (BYTE *)mat.data;
	for (int y = 0; y != source.Height; ++y) {
		BYTE *src = (BYTE *)source.Scan0 + y * source.Stride;
		BYTE *dst = (BYTE *)(destination + y * mat.step);
		memcpy(dst, src, mat.channels() * source.Width);
	}

	image->UnlockBits(&source);
}

Gdiplus::Bitmap* CImageMat::MatToCGdiImage(Mat& mat)
{
	cv::cuda::GpuMat matg;
	if (mat.empty())
		return NULL;

	//检查图像位深
	if (mat.depth() != CV_8U)
	{
		return NULL;
	}

	//cv::Mat newMat;
	if (mat.channels() == 1)
		cv::cvtColor(mat, mat, CV_GRAY2BGRA);
	else if (mat.channels() == 3)
		cv::cvtColor(mat, mat, CV_BGR2BGRA);
	else
		mat = mat;
	//Gdiplus::Bitmap src(newMat.cols, newMat.rows, newMat.step1(), PixelFormat32bppARGB, newMat.data);
	//return src.Clone(0, 0, src.GetWidth(), src.GetHeight(), PixelFormat32bppARGB);
	//Gdiplus::Bitmap* image = src.Clone(0, 0, src.GetWidth(), src.GetHeight(), PixelFormat32bppARGB);
	Gdiplus::Bitmap* image = new Gdiplus::Bitmap(mat.cols, mat.rows, mat.step1(), PixelFormat32bppARGB, mat.data);
	return image;
}

void CImageMat::BitmapToIplImage(Gdiplus::Bitmap* pBitmap, IplImage* &pIplImg)
{
	if (!pBitmap)
		return;

	if (pIplImg)
	{
		cvReleaseImage(&pIplImg);
		pIplImg = NULL;
	}
	BitmapData bmpData;
	Gdiplus::Rect rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
	pBitmap->LockBits(&rect, ImageLockModeRead, PixelFormat24bppRGB, &bmpData);
	IplImage* tempImg = cvCreateImage(cvSize(pBitmap->GetWidth(), pBitmap->GetHeight()), IPL_DEPTH_8U, 3);
	BYTE* temp = (bmpData.Stride > 0) ? ((BYTE*)bmpData.Scan0) : ((BYTE*)bmpData.Scan0 + bmpData.Stride*(bmpData.Height - 1));
	memcpy(tempImg->imageData, temp, abs(bmpData.Stride)*bmpData.Height);
	pBitmap->UnlockBits(&bmpData);
	pIplImg = tempImg;
	//判断Top-Down or Bottom-Up
	if (bmpData.Stride < 0)
		cvFlip(pIplImg, pIplImg);
}

void CImageMat::IplImageToBitmap(IplImage* pIplImg, Gdiplus::Bitmap* &pBitmap)
{
	if (!pIplImg)
		return;
	BITMAPINFOHEADER bmih;
	memset(&bmih, 0, sizeof(BITMAPINFOHEADER));
	bmih.biSize = sizeof(BITMAPINFOHEADER);
	bmih.biWidth = pIplImg->width;
	bmih.biHeight = pIplImg->height;
	bmih.biPlanes = 1;
	bmih.biBitCount = pIplImg->depth*pIplImg->nChannels;
	bmih.biSizeImage = pIplImg->imageSize;
	BYTE* pData = new BYTE[bmih.biSizeImage];
	memcpy(pData, pIplImg->imageDataOrigin, pIplImg->imageSize);
	if (pBitmap)
	{
		delete pBitmap;
		pBitmap = NULL;
	}
	pBitmap = Gdiplus::Bitmap::FromBITMAPINFO((BITMAPINFO*)&bmih, pData);
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值