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

📄 imagegeometry.cpp

📁 这是一个图像处理的程序,改变参数控制图片的大小
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	}
	if(nHeight > (nScanHeight - y)) 
	{
		::AfxMessageBox("The height of the area you defined is not obtained!");
		return FALSE;
	}

	m_dwOperation = IMAGE_GEOMETRY_ROTATE_CCW_90;

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


	//指定区域第一行最后一列开始地址.
	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;
	}

	m_dwOperation = IMAGE_GEOMETRY_ROTATE_0;

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

	//行字节数(目标子图像)
	DWORD dwWidtgBytesDst = (DWORD)nWidth * 4;

	//指定区域第一行第一列开始地址.
	BYTE* pbySrcBase = lpbyBitsSrc32 + y * dwWidthBytes + 4 * x;
	
	//目的地地址
	BYTE* pbyDst = lpbyBitsDst32;
	for(int i = 0; i < nHeight; i++)
	{
		::CopyMemory(pbyDst, pbySrcBase, dwWidtgBytesDst); 
		pbySrcBase += dwWidthBytes;
		pbyDst += dwWidtgBytesDst;
	}
	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;
}

//水平镜象,但是镜象轴为 Y 轴
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;
	}

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

	//指定区域最后一行最后一列开始地址.
	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;
}

//垂直镜象,但是镜象轴为 X 轴
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;

	//行字节数(目标子图像)
	DWORD dwWidtgBytesDst = (DWORD)nWidth * 4;

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

		::CopyMemory(pbyDst, pbySrcBase, dwWidtgBytesDst); 

		pbyDst += dwWidtgBytesDst;
		pbySrcBase -= dwWidthBytes;
	}
	return TRUE;
}

⌨️ 快捷键说明

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