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

📄 imagegeometry.cpp

📁 visual c++数字图像与图形处理中的光盘内容
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	//行字节数
	DWORD dwWidthBytes = (DWORD)nScanWidth * 4;

	m_dwOperation = IMAGE_GEOMETRY_ROTATE_CCW_90;

	//指定区域第一行最后一列开始地址.
	BYTE* pbySrcBase = lpbyBitsSrc32 + y * dwWidthBytes + 4 * (x + nWidth - 1);
	
	//目的地地址
	BYTE* pbyDst = lpbyBitsDst32;
	for(int i = 0;i < nWidth;i++)
	{
		//从上向下按列获取数据
		//逐渐向左移动
		BYTE* pbySrc = pbySrcBase;
		for(int j = 0;j < nHeight;j++)
		{
			
			BYTE* pbyCurrent = pbySrc;
			*pbyDst++ = *pbyCurrent++;
			*pbyDst++ = *pbyCurrent++;
			*pbyDst++ = *pbyCurrent++;
			pbyDst++;
			pbySrc += dwWidthBytes;
		}
		pbySrcBase -= 4;
	}
	return TRUE;
}

BOOL CImageGeometry::Rotate180(LPBYTE lpbyBitsSrc32, int x, int y, int nWidth, int nHeight, int nScanWidth, int nScanHeight, LPBYTE lpbyBitsDst32)
{
	//第一步,进行参数合法性检测
	ASSERT(lpbyBitsSrc32);
	ASSERT(lpbyBitsDst32);

	if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
	
	//有效区域的宽度和高度
	//请注意,这时,宽度和高度不得随意超过有效宽度和高度.

	if(nWidth > (nScanWidth - x)) 
	{
		::AfxMessageBox("The width of the area you defined is not obtained!");
		return FALSE;
	}
	if(nHeight > (nScanHeight - y)) 
	{
		::AfxMessageBox("The height of the area you defined is not obtained!");
		return FALSE;
	}

	//行字节数
	DWORD dwWidthBytes = (DWORD)nScanWidth * 4;


	m_dwOperation = IMAGE_GEOMETRY_ROTATE_180;

	//指定区域最后一行最后一列开始地址.
	BYTE* pbySrcBase = lpbyBitsSrc32 + (y + nHeight - 1) * dwWidthBytes + 4 * (x + nWidth - 1);
	
	//目的地地址
	BYTE* pbyDst = lpbyBitsDst32;
	for(int i = 0;i < nHeight;i++)
	{
		//
		//逐渐向左移动
		BYTE* pbySrc = pbySrcBase;
		for(int j = 0;j < nWidth;j++)
		{

			*pbyDst++ = *pbySrc++;
			*pbyDst++ = *pbySrc++;
			*pbyDst++ = *pbySrc++;
			pbyDst++;
			pbySrc -= 7;

			/*
			//下列代码是等价的.
			BYTE* pbyCurrent = pbySrc;
			*pbyDst++ = *pbyCurrent++;
			*pbyDst++ = *pbyCurrent++;
			*pbyDst++ = *pbyCurrent++;
			pbyDst++;
			pbySrc -= 4;
			*/
		}
		pbySrcBase -= dwWidthBytes;
	}
	return TRUE;
}

//旋转...,-360,0,360,...度
BOOL CImageGeometry::Rotate0(LPBYTE lpbyBitsSrc32, int x, int y, int nWidth, int nHeight, int nScanWidth, int nScanHeight, LPBYTE lpbyBitsDst32)
{
	//第一步,进行参数合法性检测
	ASSERT(lpbyBitsSrc32);
	ASSERT(lpbyBitsDst32);

	if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
	
	//有效区域的宽度和高度
	//请注意,这时,宽度和高度不得随意超过有效宽度和高度.

	if(nWidth > (nScanWidth - x)) 
	{
		::AfxMessageBox("The width of the area you defined is not obtained!");
		return FALSE;
	}
	if(nHeight > (nScanHeight - y)) 
	{
		::AfxMessageBox("The height of the area you defined is not obtained!");
		return FALSE;
	}

	//行字节数
	DWORD dwWidthBytes = (DWORD)nScanWidth * 4;


	m_dwOperation = IMAGE_GEOMETRY_ROTATE_0;

	//指定区域最后一行最后一列开始地址.
	BYTE* pbySrcBase = lpbyBitsSrc32 + y * dwWidthBytes + 4 * x;
	
	//目的地地址
	BYTE* pbyDst = lpbyBitsDst32;
	for(int i = 0;i < nHeight;i++)
	{
		//从上向下按列获取数据
		//逐渐向右移动
		BYTE* pbySrc = pbySrcBase;
		for(int j = 0;j < nWidth;j++)
		{

			*pbyDst++ = *pbySrc++;
			*pbyDst++ = *pbySrc++;
			*pbyDst++ = *pbySrc++;
			pbyDst++;
			pbySrc++;
		}
		pbySrcBase += dwWidthBytes;
	}
	return TRUE;
}


//lpbyBitsSrc32----传递源像素值,
//x,y,nWidth, nHeight,定义区域的宽度
//nScanWidth, nScanHeight,扫描宽度和扫描高度
//lpbyBitsDst32----存放最后缩放后的结果

//fTheta ---- 旋转角度

//nWidthImgDst,nHeightDst旋转后的尺寸,事实上它们可以通过nWidth, nHeight和fTheta计算出来.

BOOL CImageGeometry::Rotate(LPBYTE lpbyBitsSrc32, int x, int y, int nWidth, int nHeight, int nScanWidth, int nScanHeight,LPBYTE lpbyBitsDst32,float fTheta,int nWidthImgDst,int nHeightImgDst)
{
	//第一步,进行参数合法性检测
	ASSERT(lpbyBitsSrc32);
	ASSERT(lpbyBitsDst32);

	if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
	
	//有效区域的宽度和高度
	//请注意,这时,宽度和高度不得随意超过有效宽度和高度.

	if(nWidth > (nScanWidth - x)) 
	{
		::AfxMessageBox("The width of the area you defined is not obtained!");
		return FALSE;
	}
	if(nHeight > (nScanHeight - y)) 
	{
		::AfxMessageBox("The height of the area you defined is not obtained!");
		return FALSE;
	}

	m_dwOperation = IMAGE_GEOMETRY_ROTATE;


	//将角度转化成弧度
	float fRadTheta = (float)(fTheta * PIE / 180.0);

	//计算其三角函数值
	float fSinTheta = (float)sin(fRadTheta);
	float fCosTheta = (float)cos(fRadTheta);

	///////////////////////////////////////////////////////
	//首先考查是否是旋转特殊的角度.
	///////////////////////////////////////////////////////

	if((nWidthImgDst == nHeight) && (nHeightImgDst == nWidth))
	{
		// ..., -270, 90, 450,...,
		if(fSinTheta > 0.99f)
			return RotateCCW90(lpbyBitsSrc32,x,y,nWidth,nHeight,nScanWidth,nScanHeight,lpbyBitsDst32);
		
		// ..., -450, -90, 270,...,
		else if(fSinTheta < -0.99f)
			return RotateCW90(lpbyBitsSrc32,x,y,nWidth,nHeight,nScanWidth,nScanHeight,lpbyBitsDst32);
	}

	
	if((nWidthImgDst == nWidth) && (nHeightImgDst == nHeight))
	{
		// ...,-540,-180,180,540,...,
		if(fCosTheta < -0.99f)
			return Rotate180(lpbyBitsSrc32,x,y,nWidth,nHeight,nScanWidth,nScanHeight,lpbyBitsDst32);
		// ...,-360,0,360,
		else if (fCosTheta > 0.99f)
			return Rotate0(lpbyBitsSrc32,x,y,nWidth,nHeight,nScanWidth,nScanHeight,lpbyBitsDst32);
	}

	//////////////////////////////////////////////////
	//处理非特殊角度
	//////////////////////////////////////////////////

	//绝对旋转中心,相对于原图像坐标系统.
	int nAbsCenterX = x + nWidth / 2;
	int nAbsCenterY = y + nHeight / 2;

	//相对旋转中心,它们具有相同的x,y坐标.相对于目标图像
	int nRelCenterX = nWidthImgDst / 2;
	int nRelCenterY = nHeightImgDst / 2;

	//行字节数
	DWORD dwWidthBytes = (DWORD)nScanWidth * 4;

	
	//目的地地址
	BYTE* pbyDst = lpbyBitsDst32;

	//开始计算
	//按行进行扫描计算
	for(int i = 0;i < nHeightImgDst;i++)//y
	{
		//右手直角坐标系下,坐标值为 i 的纵坐标表示
		int yy = nRelCenterY - i;
		for(int j = 0; j < nWidthImgDst;j++)//x
		{
			//右手直角坐标系下,坐标值为 j 的横坐标表示
			int xx = j - nRelCenterX;

			//进行反向变换,旋转角度: -theta
			float fXInverse = xx * fCosTheta + yy * fSinTheta;
			float fYInverse = yy * fCosTheta - xx * fSinTheta;

			//变成左手坐标系
			fYInverse = -fYInverse;
			fXInverse += nAbsCenterX;
			fYInverse += nAbsCenterY;

			//近邻坐标值
			//
			int nNearX = (int)fXInverse;
			int nNearY = (int)fYInverse;
			if((nNearX >= x) && (nNearX <= (x + nWidth - 1)) &&
			   (nNearY >= y) && (nNearY <= (y + nHeight - 1)))
			{
				//插值参数
				float fu = fXInverse - nNearX;
				float fv = fYInverse - nNearY;

				//近邻点的地址
				BYTE* pbySrc = lpbyBitsSrc32 + nNearY * dwWidthBytes + 4 * nNearX;
				PIXELCOLORRGB rgb = Interpolate(pbySrc,nNearX,nNearY,fu,fv,nScanWidth, nScanHeight);
			
				*pbyDst++ = rgb.blue;
				*pbyDst++ = rgb.green;
				*pbyDst++ = rgb.red;
				pbyDst++;

			}
			else
				pbyDst += 4;
		}
	}
	return TRUE;
}

//水平镜象
BOOL CImageGeometry::MirrorY(LPBYTE lpbyBitsSrc32, int x, int y, int nWidth, int nHeight, int nScanWidth, int nScanHeight, LPBYTE lpbyBitsDst32)
{
	//第一步,进行参数合法性检测
	ASSERT(lpbyBitsSrc32);
	ASSERT(lpbyBitsDst32);

	if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
	
	//有效区域的宽度和高度
	//请注意,这时,宽度和高度不得随意超过有效宽度和高度.

	if(nWidth > (nScanWidth - x)) 
	{
		::AfxMessageBox("The width of the area you defined is not obtained!");
		return FALSE;
	}
	if(nHeight > (nScanHeight - y)) 
	{
		::AfxMessageBox("The height of the area you defined is not obtained!");
		return FALSE;
	}

	//行字节数
	DWORD dwWidthBytes = (DWORD)nScanWidth * 4;

	m_dwOperation = IMAGE_GEOMETRY_MIRROR_Y;
	//指定区域最后一行最后一列开始地址.
	BYTE* pbySrcBase = lpbyBitsSrc32 + y * dwWidthBytes + 4 * (x + nWidth - 1);
	
	//目的地地址
	BYTE* pbyDst = lpbyBitsDst32;
	for(int i = 0;i < nHeight;i++)
	{
		//从上向下按列获取数据
		//逐渐向左移动
		BYTE* pbySrc = pbySrcBase;
		for(int j = 0;j < nWidth;j++)
		{

			*pbyDst++ = *pbySrc++;
			*pbyDst++ = *pbySrc++;
			*pbyDst++ = *pbySrc++;
			pbyDst++;
			pbySrc -= 7;
		}
		pbySrcBase += dwWidthBytes;
	}
	return TRUE;
}

//垂直镜象
BOOL CImageGeometry::MirrorX(LPBYTE lpbyBitsSrc32, int x, int y, int nWidth, int nHeight, int nScanWidth, int nScanHeight, LPBYTE lpbyBitsDst32)
{
	//第一步,进行参数合法性检测
	ASSERT(lpbyBitsSrc32);
	ASSERT(lpbyBitsDst32);

	if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
	
	//有效区域的宽度和高度
	//请注意,这时,宽度和高度不得随意超过有效宽度和高度.

	if(nWidth > (nScanWidth - x)) 
	{
		::AfxMessageBox("The width of the area you defined is not obtained!");
		return FALSE;
	}
	if(nHeight > (nScanHeight - y)) 
	{
		::AfxMessageBox("The height of the area you defined is not obtained!");
		return FALSE;
	}

	m_dwOperation = IMAGE_GEOMETRY_MIRROR_X;
	//行字节数
	DWORD dwWidthBytes = (DWORD)nScanWidth * 4;

	//指定区域最后一行最后一列开始地址.
	BYTE* pbySrcBase = lpbyBitsSrc32 + (y + nHeight - 1) * dwWidthBytes + 4 * x;
	
	//目的地地址
	BYTE* pbyDst = lpbyBitsDst32;
	for(int i = 0;i < nHeight;i++)
	{
		//从上向下按列获取数据
		//逐渐向左移动
		BYTE* pbySrc = pbySrcBase;
		for(int j = 0;j < nWidth;j++)
		{

			*pbyDst++ = *pbySrc++;
			*pbyDst++ = *pbySrc++;
			*pbyDst++ = *pbySrc++;
			pbyDst++;
			pbySrc++;
		}
		pbySrcBase -= dwWidthBytes;
	}
	return TRUE;
}

⌨️ 快捷键说明

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