⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 geotrans.cpp

📁 用C++实现的数字图像处理各个算法源代码 我精心整理的 很难的啊 希望可以给大家带来帮助
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	//获得图像宽度和高度
	int nWidth = m_pDibObject->GetWidth();
	int nHeight = m_pDibObject->GetHeight();

	//定义变量
	unsigned char *pOldBuffer; 
	unsigned char *pOldBits, *pNewBits;
	unsigned char *pOldTemp, *pNewTemp;
	unsigned char *pTemp1, *pTemp2;
	BITMAPFILEHEADER *pOldBFH;
	BITMAPINFOHEADER *pOldBIH;
	RGBQUAD *pOldPalette;
	int nWidthBytes, nNumColors, x, y;

	//原图像指针
	pOldBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes, 
																m_pDibObject->GetNumBits() );
	if( pOldBuffer == NULL ) return( FALSE );

	//原图像文件头指针
	pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
	//原图像信息头指针
	pOldBIH = (BITMAPINFOHEADER *) &pOldBuffer[sizeof(BITMAPFILEHEADER)];
	//原图像颜色数
	nNumColors = m_pDibObject->GetNumColors();
	//原图像调色板指针
	pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER)
									+sizeof(BITMAPINFOHEADER)];
	//原图像数据指针
	pOldBits = (unsigned char *) &pOldBuffer[sizeof(BITMAPFILEHEADER)
											+sizeof(BITMAPINFOHEADER)
											+nNumColors*sizeof(RGBQUAD)];

	//为新图像数据区分配内存
	DWORD dwNewSize;
	HGLOBAL hNewDibBits;
	//新图像数据区大小
	dwNewSize = nWidthBytes * nHeight;
	//为新图像分配内存
	hNewDibBits = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
	if( hNewDibBits == NULL )
	{
		m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
		::GlobalUnlock( m_pDibObject->GetDib() );
		return( FALSE );
	}

	//新图像指针
	pNewBits = (unsigned char *) ::GlobalLock( hNewDibBits );
	if( pNewBits == NULL )
	{
		::GlobalFree( hNewDibBits );
		m_pDibObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
		::GlobalUnlock( m_pDibObject->GetDib() );
		return( FALSE );
	}

	//用255(白色)填充新图像数据区
	memset(pNewBits, (BYTE)255, nWidthBytes * nHeight );
	
	//由图像位数确定的移动字节数
	int nMovedBits = 1;
	switch( m_pDibObject->GetNumBits() )
	{
	case 8:	
		nMovedBits = 1;
		break;
	case 16:
		nMovedBits = 2;
		break;
	case 24:
		nMovedBits = 3;
		break;
	case 32:
		nMovedBits = 4;
		break;
	}

	//判断镜像方式
	if (bDirection)
	{
		//水平镜像
		
		//垂直中轴坐标
		int nMiddleX = nWidth / 2;
		
		//针对图像每行进行操作
		for(y = 0; y < nHeight; y++)
		{
			//指向图像的倒数第y行
			pOldTemp = pOldBits;
			pOldTemp +=  y * nWidthBytes;
			pNewTemp = pNewBits;
			pNewTemp +=  y * nWidthBytes;
			
			//针对每行图像左半部分进行操作
			for(x = 0; x <= nMiddleX; x++)
			{
				//将源图像第x个像素复制到新图像倒数第x个像素
				pTemp1 = pOldTemp + x * nMovedBits;
				pTemp2 = pNewTemp + (nWidth -1 - x) * nMovedBits;
				memcpy(pTemp2, pTemp1, nMovedBits);
				//将源图像倒数第x个像素复制到新图像第x个像素
				pTemp1 = pOldTemp + (nWidth -1 - x) * nMovedBits;
				pTemp2 = pNewTemp + x * nMovedBits;
				memcpy(pTemp2, pTemp1, nMovedBits);
			}
		
		}
	}
	else
	{
		//垂直镜像

		//水平中轴坐标
		int nMiddleY = nHeight / 2;
		//针对上半图像进行操作
		for(y = 0; y <= nMiddleY; y++)
		{
			
			//指向源图像倒数第y行像素起点的指针
			pOldTemp = pOldBits;
			pOldTemp +=  y * nWidthBytes;

			//指向新图像第y行像素起点的指针
			pNewTemp = pNewBits;
			pNewTemp +=  (nHeight - 1 - y) * nWidthBytes;
			
			//将源图像倒数第y行像素复制到新图像第y行
			memcpy(pNewTemp, pOldTemp, nWidthBytes);

			//指向源图像第y行像素起点的指针
			pOldTemp = pOldBits;
			pOldTemp +=  (nHeight - 1 - y) * nWidthBytes;

			//指向新图像倒数第y行像素起点的指针
			pNewTemp = pNewBits;
			pNewTemp +=  y * nWidthBytes;
			
			//将源图像第y行像素复制到新图像倒数第y行
			memcpy(pNewTemp, pOldTemp, nWidthBytes);
		}
	}

	//用新图像数据填充原图像数据区
	memcpy( pOldBits, pNewBits, nWidthBytes * nHeight );

	::GlobalFree( hNewDibBits );
	::GlobalUnlock( m_pDibObject->GetDib() );


	return TRUE;
}

/**********************************************************************
* 函数名称:BOOL Transpose()
* 基本功能:本函数对传入的CDibObject对象中的图像进行转置操作。如果进行此
*			调整之前没有指定一个CDibObject对象指针,则必须在调整时加以指定。
* 参数说明:CDibObject *pDibObject, 默认为NULL
* 返回值: BOOL  - 转置成功返回TRUE,否则返回FALSE。
**********************************************************************/
BOOL CGeoTrans::Transpose(CDibObject *pDibObject)
{
	if( pDibObject != NULL ) m_pDibObject = pDibObject;
	//无CDibObject对象, 返回FALSE
	if( m_pDibObject == NULL ) return( FALSE );

	//获得图像宽度和高度
	int nOldWidth = m_pDibObject->GetWidth();
	int nOldHeight = m_pDibObject->GetHeight();
	//转置后图像的宽度和高度
	int nNewWidth = nOldHeight;
	int nNewHeight = nOldWidth;

	//定义变量
	unsigned char *pOldBuffer, *pNewBuffer; 
	unsigned char *pOldBits, *pNewBits;
	unsigned char *pOldTemp, *pNewTemp;
	BITMAPFILEHEADER *pOldBFH, *pNewBFH;
	BITMAPINFOHEADER *pOldBIH, *pNewBIH;
	RGBQUAD *pOldPalette, *pNewPalette;
	int nOldWidthBytes, nNewWidthBytes, nNumColors, x, y;

	//原图像指针
	pOldBuffer = (unsigned char *) 
				m_pDibObject->GetDIBPointer( &nOldWidthBytes, 
				m_pDibObject->GetNumBits(), 
				&nNewWidthBytes, nNewWidth );
	if( pOldBuffer == NULL ) return( FALSE );

	//原图像文件头指针
	pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
	//原图像信息头指针
	pOldBIH = (BITMAPINFOHEADER *) 
			&pOldBuffer[sizeof(BITMAPFILEHEADER)];
	//原图像颜色数
	nNumColors = m_pDibObject->GetNumColors();
	//原图像调色板指针
	pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER)
									+sizeof(BITMAPINFOHEADER)];
	//原图像数据指针
	pOldBits = (unsigned char *)
				&pOldBuffer[sizeof(BITMAPFILEHEADER)
				+sizeof(BITMAPINFOHEADER)
				+nNumColors*sizeof(RGBQUAD)];

	DWORD dwNewSize;
	HGLOBAL hNewDib;

	//新图像大小(包括文件头、信息头、调色板和图像数据)
	dwNewSize = (DWORD) nNumColors * sizeof( RGBQUAD ) +
						sizeof( BITMAPFILEHEADER ) + 
						sizeof( BITMAPINFOHEADER ) + 
						nNewWidthBytes * nNewHeight;
	//为新图像分配内存
	hNewDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
	if( hNewDib == NULL )
	{
		m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
		::GlobalUnlock( m_pDibObject->GetDib() );
		return( FALSE );
	}

	//新图像指针
	pNewBuffer = (unsigned char *) ::GlobalLock( hNewDib );
	if( pNewBuffer == NULL )
	{
		::GlobalFree( hNewDib );
		m_pDibObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
		::GlobalUnlock( m_pDibObject->GetDib() );
		return( FALSE );
	}

	//新图像文件头指针
	pNewBFH = (BITMAPFILEHEADER *) pNewBuffer;
	//新图像信息头指针
	pNewBIH = (BITMAPINFOHEADER *) &pNewBuffer[sizeof(BITMAPFILEHEADER)];
	//新图像调色板指针
	pNewPalette = (RGBQUAD *) &pNewBuffer[sizeof(BITMAPFILEHEADER)
							+sizeof(BITMAPINFOHEADER)];
	//新图像数据指针
	pNewBits = (unsigned char *) &pNewBuffer[sizeof(BITMAPFILEHEADER)
									+sizeof(BITMAPINFOHEADER)
									+nNumColors*sizeof(RGBQUAD)];

	//用255(白色)填充新图像数据区
	memset(pNewBits, (BYTE)255, nNewWidthBytes * nNewHeight );

	//用原图像文件头数据填充新图像文件头
	memcpy( pNewBFH, pOldBFH, sizeof(BITMAPFILEHEADER) );

	//用原图像信息头数据填充新图像信息头
	memcpy( pNewBIH, pOldBIH, sizeof(BITMAPINFOHEADER) );

	//调整文件总字节数
	pNewBFH->bfSize = dwNewSize;

	//调整新图像的宽度和高度
	pNewBIH->biWidth = nNewWidth;
	pNewBIH->biHeight = nNewHeight;

	//pNewBIH->biBitCount = nNewBitsPerPixel;
	pNewBIH->biSizeImage = nNewWidthBytes * nNewHeight;
	pNewBIH->biClrUsed = nNumColors;
	pNewBFH->bfSize = sizeof( BITMAPFILEHEADER ) 
					+ sizeof( BITMAPINFOHEADER ) 
					+ nNumColors * sizeof( RGBQUAD ) 
					+ pNewBIH->biSizeImage;
	pNewBFH->bfOffBits = sizeof( BITMAPFILEHEADER ) 
						+ sizeof( BITMAPINFOHEADER ) 
						+ nNumColors * sizeof( RGBQUAD );

	//用原图像调色板填充新图像调色板
	if(nNumColors != 0)
		memcpy( pNewPalette, pOldPalette, nNumColors*sizeof(RGBQUAD) );

	//由图像位数确定的移动字节数
	int nMovedBits = 1;
	switch( m_pDibObject->GetNumBits() )
	{
	case 8:	
		nMovedBits = 1;
		break;
	case 16:
		nMovedBits = 2;
		break;
	case 24:
		nMovedBits = 3;
		break;
	case 32:
		nMovedBits = 4;
		break;
	}

	// 针对图像每行进行操作
	for(y = 0; y < nOldHeight; y++)
	{
		//指向源图像第y行
		pOldTemp = pOldBits;
		pOldTemp += (nOldHeight - 1 -y) * nOldWidthBytes;
		// 针对每行图像每列进行操作
		for(x = 0; x < nOldWidth; x++)
		{
			//指向转置后的图像第x行,第y个像素的指针
			//注意此处宽度和高度应该互换
			pNewTemp = pNewBits;
			pNewTemp += (nNewHeight - 1 - x) * nNewWidthBytes;
			pNewTemp += y * nMovedBits;
			
			//复制像素
			memcpy(pNewTemp, pOldTemp, nMovedBits);
			pOldTemp += nMovedBits;			
		}
	}

	//将内存解锁和将不再使用的内存释放
	::GlobalUnlock( m_pDibObject->GetDib() );
	::GlobalFree( m_pDibObject->GetDib() );
	::GlobalUnlock( hNewDib );
	//将新图像设置为当前图像
	m_pDibObject->SetDib( hNewDib );

	m_pDibObject->ProcessImageHeader();

	return TRUE;
}

////////////////////////////////////////////////////////////////////////
//BOOL ZoomImage()  
//----------------------------------------------------------------------
//基本功能:本函数对传入的CDibObject对象中的图像进行缩放操作。如果进行
//			此调整之前没有指定一个CDibObject对象指针,则必须在调整时加
//			以指定。
//----------------------------------------------------------------------
//参数说明:float fXZoomRatio	- X轴方向缩放比率
//			float fYZoomRatio	- Y轴方向缩放比率
//			BOOL bBilinear		- TRUE为双线性插值,FALSE为最邻近插值
//			CDibObject *pDibObject, 默认为NULL
//----------------------------------------------------------------------
//返回:BOOL:成功返回TRUE,失败返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CGeoTrans::ZoomImage(float fXZoomRatio, 
							   float fYZoomRatio,
							   BOOL bBilinear,
							   CDibObject *pDibObject)
{
	if( pDibObject != NULL ) m_pDibObject = pDibObject;
	//无CDibObject对象, 返回FALSE
	if( m_pDibObject == NULL ) return( FALSE );

	//获得图像宽度和高度
	int nOldWidth = m_pDibObject->GetWidth();
	int nOldHeight = m_pDibObject->GetHeight();

	// 计算缩放后的图像实际宽度
	int nNewWidth, nNewHeight;
	// 此处直接加0.5是由于强制类型转换时不四舍五入,而是直接截去小数部分
	nNewWidth = (int)(nOldWidth * fXZoomRatio + 0.5);
	
	// 计算缩放后的图像高度
	nNewHeight = (int)(nOldHeight * fYZoomRatio + 0.5);

	//定义变量
	unsigned char *pOldBuffer, *pNewBuffer; 
	unsigned char *pOldBits, *pNewBits;
	unsigned char *pOldTemp, *pNewTemp;
	BITMAPFILEHEADER *pOldBFH, *pNewBFH;
	BITMAPINFOHEADER *pOldBIH, *pNewBIH;
	RGBQUAD *pOldPalette, *pNewPalette;
	int nOldWidthBytes, nNewWidthBytes, nNumColors, x, y;

	//原图像指针
	pOldBuffer = (unsigned char *) 
				m_pDibObject->GetDIBPointer( &nOldWidthBytes, 
				m_pDibObject->GetNumBits(), 
				&nNewWidthBytes, nNewWidth );
	if( pOldBuffer == NULL ) return( FALSE );

	//原图像文件头指针
	pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
	//原图像信息头指针
	pOldBIH = (BITMAPINFOHEADER *) 
			&pOldBuffer[sizeof(BITMAPFILEHEADER)];
	//原图像颜色数
	nNumColors = m_pDibObject->GetNumColors();
	//原图像调色板指针
	pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER)
									+sizeof(BITMAPINFOHEADER)];
	//原图像数据指针
	pOldBits = (unsigned char *)
				&pOldBuffer[sizeof(BITMAPFILEHEADER)
				+sizeof(BITMAPINFOHEADER)
				+nNumColors*sizeof(RGBQUAD)];

	DWORD dwNewSize;
	HGLOBAL hNewDib;

	//新图像大小(包括文件头、信息头、调色板和图像数据)
	dwNewSize = (DWORD) nNumColors * sizeof( RGBQUAD ) +
						sizeof( BITMAPFILEHEADER ) + 
						sizeof( BITMAPINFOHEADER ) + 
						nNewWidthBytes * nNewHeight;
	//为新图像分配内存
	hNewDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
	if( hNewDib == NULL )
	{
		m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
		::GlobalUnlock( m_pDibObject->GetDib() );
		return( FALSE );
	}

	//新图像指针
	pNewBuffer = (unsigned char *) ::GlobalLock( hNewDib );
	if( pNewBuffer == NULL )
	{
		::GlobalFree( hNewDib );
		m_pDibObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
		::GlobalUnlock( m_pDibObject->GetDib() );
		return( FALSE );
	}

	//新图像文件头指针
	pNewBFH = (BITMAPFILEHEADER *) pNewBuffer;
	//新图像信息头指针
	pNewBIH = (BITMAPINFOHEADER *) &pNewBuffer[sizeof(BITMAPFILEHEADER)];
	//新图像调色板指针
	pNewPalette = (RGBQUAD *) &pNewBuffer[sizeof(BITMAPFILEHEADER)
							+sizeof(BITMAPINFOHEADER)];
	//新图像数据指针
	pNewBits = (unsigned char *) &pNewBuffer[sizeof(BITMAPFILEHEADER)
									+sizeof(BITMAPINFOHEADER)
									+nNumColors*sizeof(RGBQUAD)];

	//用255(白色)填充新图像数据区
	memset(pNewBits, (BYTE)255, nNewWidthBytes * nNewHeight );

	//用原图像文件头数据填充新图像文件头
	memcpy( pNewBFH, pOldBFH, sizeof(BITMAPFILEHEADER) );

	//用原图像信息头数据填充新图像信息头
	memcpy( pNewBIH, pOldBIH, sizeof(BITMAPINFOHEADER) );

	//调整文件总字节数
	pNewBFH->bfSize = dwNewSize;

	//调整新图像的宽度和高度
	pNewBIH->biWidth = nNewWidth;
	pNewBIH->biHeight = nNewHeight;

	//pNewBIH->biBitCount = nNewBitsPerPixel;
	pNewBIH->biSizeImage = nNewWidthBytes * nNewHeight;
	pNewBIH->biClrUsed = nNumColors;
	pNewBFH->bfSize = sizeof( BITMAPFILEHEADER ) 
					+ sizeof( BITMAPINFOHEADER ) 
					+ nNumColors * sizeof( RGBQUAD ) 
					+ pNewBIH->biSizeImage;
	pNewBFH->bfOffBits = sizeof( BITMAPFILEHEADER ) 
						+ sizeof( BITMAPINFOHEADER ) 
						+ nNumColors * sizeof( RGBQUAD );

	//用原图像调色板填充新图像调色板
	if(nNumColors != 0)
		memcpy( pNewPalette, pOldPalette, nNumColors*sizeof(RGBQUAD) );

	//由图像位数确定的移动字节数
	int nMovedBits = 1;
	switch( m_pDibObject->GetNumBits() )
	{
	case 8:	
		nMovedBits = 1;
		break;
	case 16:
		nMovedBits = 2;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -