通过操作BMP文件的RGB值实现BMP文件的旋转,锐化,二值化,轮廓提取,边缘检测,合并等功能(二)

在将所有文件转为32Bit位图后,就可以进行特效处理了,首先是文件旋转

/*********************************************************************************
*	RotateImage(int nAngle)
*	按照90度的角度,顺时针或者逆时针旋转图片
*	nAngle = 0 逆时针旋转
*	nAngle = 1 顺时针旋转
**********************************************************************************/
void CImageEditor::RotateImage(int nAngle)
{
	//原来的宽和高互换
	unsigned int nImageWidthAfterRoate, nImageHeightAfterRoate;
	nImageWidthAfterRoate = nImageHeightAfterRoate = 0;
	unsigned int nImageWidthOri = m_pBitmapInfo->bmiHeader.biWidth; //旋转前的宽
	unsigned int nImageHeightOri = abs(m_pBitmapInfo->bmiHeader.biHeight);
	nImageWidthAfterRoate = abs(m_pBitmapInfo->bmiHeader.biHeight); //旋转后的宽
	nImageHeightAfterRoate = m_pBitmapInfo->bmiHeader.biWidth;
	unsigned int nBytesPerLine = ((nImageWidthAfterRoate * m_pBitmapInfo->bmiHeader.biBitCount + 31) / 32) * 4; //旋转后的每行的字节数
	unsigned int nTotalImageBytesData = nBytesPerLine * nImageHeightAfterRoate; //旋转后的总字节数
	unsigned int nBytesPerLineOri = ((nImageWidthOri * m_pBitmapInfo->bmiHeader.biBitCount + 31) / 32) * 4; //旋转前的每行的字节数
	m_pBitmapInfo->bmiHeader.biSizeImage = nTotalImageBytesData;
	BYTE *pImageBytesData = new BYTE[nTotalImageBytesData]; //旋转后的数据
	ASSERT(pImageBytesData != NULL);
	memset(pImageBytesData, 0, nTotalImageBytesData);
	int nOffset = nBytesPerLine - nImageWidthAfterRoate * m_pBitmapInfo->bmiHeader.biBitCount / 8; 
	for(unsigned int nHeight = 0, int nHeightR =nImageHeightOri -1; nHeight < nImageHeightOri; nHeight++, nHeightR--)
	{
		for (unsigned int nWeidth = 0, int nWeidthR = nImageWidthOri -1; nWeidth < nImageWidthOri; nWeidth++, nWeidthR--)
		{
			int R, G, B, Alpha;
			R = G = B = Alpha = 0;
			Alpha = m_pImageBytesData[nBytesPerLineOri * nHeight + nWeidth * 4 + 3];
			R = m_pImageBytesData[nBytesPerLineOri * nHeight + nWeidth * 4 + 2]; 
			G = m_pImageBytesData[nBytesPerLineOri * nHeight + nWeidth * 4 + 1]; 
			B =	m_pImageBytesData[nBytesPerLineOri * nHeight + nWeidth * 4];   

			if (nAngle == 0) 
			{
				//左转
				pImageBytesData[nBytesPerLine * nWeidth + nHeightR * 4 +3] = Alpha;
				pImageBytesData[nBytesPerLine * nWeidth + nHeightR * 4 +2] = R;
				pImageBytesData[nBytesPerLine * nWeidth + nHeightR * 4 + 1] = G;
				pImageBytesData[nBytesPerLine * nWeidth + nHeightR * 4] = B;
			}
			else
			{
				//右转
				pImageBytesData[nBytesPerLine * nWeidthR + nHeight * 4 +3] = Alpha;
				pImageBytesData[nBytesPerLine * nWeidthR + nHeight * 4 +2] = R;
				pImageBytesData[nBytesPerLine * nWeidthR + nHeight * 4 + 1] = G;
				pImageBytesData[nBytesPerLine * nWeidthR + nHeight * 4] = B;
			}
		}
	}

	//删除原来的图像数据
	delete []m_pImageBytesData;
	m_pImageBytesData = NULL;
	m_pImageBytesData = new BYTE[nTotalImageBytesData];
	memset(m_pImageBytesData, 0, nTotalImageBytesData);

	memcpy(m_pImageBytesData, pImageBytesData, nTotalImageBytesData); //赋值旋转后数据给m_pImageBytesData
	delete [] pImageBytesData;
	pImageBytesData = NULL;
	
	//在m_pBitmapInfo宽高互换
	m_pBitmapInfo->bmiHeader.biWidth = nImageWidthAfterRoate;
	m_pBitmapInfo->bmiHeader.biHeight = nImageHeightAfterRoate;
}

灰度图像处理。百度百科:把白色与黑色之间按对数关系分为若干等级,称为灰度。灰度分为256阶。用灰度表示的图像称作灰度图。灰度图的好处是每个像素的RGB分量都是一样的,如R=G=B =250, 虽然失去彩色,但是也能很直观的显示图像,对后期的边缘检测,二值化等实现起来会很方便。至于如何修改RGB分量的值,网上有很多算法,我只是取了其中一个。

/*****************************************************************************************
*	ConvertToGrayBitmap()
*	将彩色图转为灰度图,灰度图的每个RGB分量都是一样的
*	转换公式:Gray = (R*30 + G*59 + B*11 + 50) / 100
*****************************************************************************************/
BOOL CImageEditor::ConvertToGrayBitmap()
{
	if (m_bIsGrayImage)
		return FALSE;
	unsigned int nImageHeight = abs(m_pBitmapInfo->bmiHeader.biHeight);
	unsigned int nImageWidth = m_pBitmapInfo->bmiHeader.biWidth;
	unsigned int nBytesPerLine = ((nImageWidth * m_pBitmapInfo->bmiHeader.biBitCount + 31) / 32) * 4; 
	int nOffset = nBytesPerLine - nImageWidth * m_pBitmapInfo->bmiHeader.biBitCount / 8; 
	int R, G, B, Alpha, Gray;
	R = G = B = Alpha = Gray = 0;
	for(unsigned int nHeight = 0; nHeight < nImageHeight; nHeight++)
	{
		for (unsigned int nWidth = 0; nWidth < nImageWidth; nWidth++)
		{
			
			Alpha = m_pImageBytesData[nBytesPerLine * nHeight + nWidth * 4 + 3];
			R = m_pImageBytesData[nBytesPerLine * nHeight + nWidth * 4 + 2]; 
			G = m_pImageBytesData[nBytesPerLine * nHeight + nWidth * 4 + 1]; 
			B =	m_pImageBytesData[nBytesPerLine * nHeight + nWidth * 4];  
			Gray = (R*30 + G*59 + B*11 + 50) / 100;
			m_pImageBytesData[nBytesPerLine * nHeight + nWidth * 4 + 3] = Alpha;
			m_pImageBytesData[nBytesPerLine * nHeight + nWid
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: bmp图像锐化是一种通过增强图像中的细节和边缘来改善图像清晰度的技术。下面是一个简单的方法来实现bmp图像的锐化。 首先,我们需要加载bmp图像,并将其转换为灰度图像以便于处理。然后,我们可以应用一个锐化滤波器来增强图像的边缘信息。一种常用的锐化滤波器是拉普拉斯滤波器。 拉普拉斯滤波器是一个3x3的矩阵,其中心为8,周围的为-1。我们需要在整个图像上应用该滤波器。具体地,我们将滤波器矩阵与图像中的每个像素相乘,然后将乘积求和,最后将结果赋给目标图像的对应像素。 在应用滤波器之后,我们还可以使用一个调整参数来增加图像的锐化效果。调整参数可以控制图像中的高频信息的强度。通过增加调整参数的,图像中的边缘和细节会变得更加明显。 最后,我们将锐化后的图像保存为一个新的bmp文件,并显示出来供用户观察。 这是一个简单的方法来实现bmp图像的锐化。当然,还有很多其他的方法和算法可以用于图像锐化,例如使用卷积神经网络等高级技术。 ### 回答2: 要将bmp图像进行锐化,可以使用不同的算法和技术来增强图像的边缘和细节。以下是一种可能的方法: 1. 读取bmp图像:首先需要从文件中读取bmp图像数据,包括宽度、高度和像素。 2. 灰度化处理:将彩色图像转换为灰度图像,可以通过将每个像素的红、绿、蓝分量的加权平均作为灰度实现。 3. 应用锐化算法:常用的锐化算法是拉普拉斯算子,它可以通过应用一个特定的卷积核来增强图像的边缘。对于每个像素,将其与周围像素进行卷积运算,并将结果作为锐化后的像素。这样可以提高图像的清晰度和边缘的明确性。 4. 调整对比度和亮度:锐化后的图像可能出现对比度和亮度不均匀的问题。可以通过调整图像的亮度和对比度来改善图像的视觉效果。可以使用简单的线性拉伸或非线性变换来实现,例如使用伽马校正来增加对比度。 5. 保存图像:完成锐化处理后,将结果保存为新的bmp图像文件,以便进一步使用或显示。 需要注意的是,锐化处理有时可能导致图像出现噪点或锯齿状边缘。为了减少这些不良效果,可以在锐化处理前后应用平滑滤波器或边缘保护滤波器来平衡图像的细节和噪点。 ### 回答3: 要对 BMP 图像进行锐化处理,可以使用一些图像处理算法来提高图像的清晰度和细节。下面是一种常见的基于卷积的锐化算法的步骤: 1. 首先,将 BMP 图像转换为维灰度图像,即将 RGB 转化为灰度级。 2. 然后,为了处理图像边界像素,可以对图像进行边界扩展。边界扩展的方法可以选择复制边界像素,或者使用零填充。 3. 接下来,定义一个锐化滤波器。常用的锐化滤波器是拉普拉斯(Laplacian)滤波器。通过将图像与拉普拉斯滤波器进行卷积运算,可以增强图像的高频细节。 4. 将拉普拉斯滤波器应用于图像,通过卷积运算,计算滤波器与图像各个像素的互相关结果。 5. 将卷积结果与原始图像进行相加操作,得到锐化后的图像。这一步是为了将原始图像的低频分量与滤波器处理后的高频分量相结合,从而增强图像的细节信息。 6. 最后,将处理后的图像保存为 BMP 格式。 这是一种基本的图像锐化方法,可以针对具体的应用和需求进行调整和改进。通过使用不同的滤波器和参数,可以获得不同程度的锐化效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值