单色位图旋转90度

 

bool RotateBmp(const char* szFileName)
{
	// 读取文件头
	BITMAPFILEHEADER	strBmpHead;
	BITMAPINFOHEADER	strBmpBitmap;
	RGBQUAD bmprgb1 = {0,0,0,0};
	RGBQUAD bmprgb2 = {255,255,255,0};
	byte	*pAllContent=NULL;
	
	memset((void*)&strBmpHead,  0, sizeof(strBmpHead));
	memset((void*)&strBmpBitmap,0, sizeof(strBmpBitmap));
	
	CFile openFile;
	char filehead[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
	
	//char conent_information[40];
	if(!openFile.Open(szFileName, CFile::modeRead))
	{
		return false;
	}
	
	if(openFile.Read(filehead, sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)) != sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER))
	{
		//this->MessageBox("读取数据失败!");
		openFile.Close();
		return false;
	}
	
	memcpy((void*)&strBmpHead, filehead, sizeof(BITMAPFILEHEADER));
	memcpy((void*)&strBmpBitmap, filehead+sizeof(BITMAPFILEHEADER),sizeof(BITMAPINFOHEADER));
	
	if(0x424d == strBmpHead.bfType)
	{
		//this->MessageBox("文件格式错误!");
		openFile.Close();
		return false;	
	}

	if (1 != strBmpBitmap.biBitCount)
	{
		openFile.Close();
		return false;
	}

	if (openFile.Read((void*)&bmprgb1, sizeof(bmprgb1)) != sizeof(bmprgb1))
	{
		openFile.Close();
		return false;
	}
	if (openFile.Read((void*)&bmprgb2, sizeof(bmprgb2)) != sizeof(bmprgb2))
	{
		openFile.Close();
		return false;
	}

	
	DWORD allLength = strBmpHead.bfSize - strBmpHead.bfOffBits;
	openFile.Seek(strBmpHead.bfOffBits, CFile::begin);
	
	
	//将数据进行分析,数据时正确读出来。
	pAllContent = new byte[sizeof(byte)*allLength];
	if(NULL == pAllContent)
	{
	//	MessageBox("开辟空间失败!");
		openFile.Close();
		return false;
	}
	
	DWORD length = openFile.Read(pAllContent, allLength);
	if(allLength != length)
	{
		//this->MessageBox("文件长度错误,读取数据失败!");
		openFile.Close();
		return false;
	}
	openFile.Close();

	//分配空间
	LONG nNewWidth = strBmpBitmap.biHeight;
    LONG nNewHeight = strBmpBitmap.biWidth ;
	LONG nNewBMPRowByte = ((nNewWidth*strBmpBitmap.biBitCount + 31)/8)/4*4;		//一行占得字节数


	//将数据进行分析,数据时正确读出来。
	byte *pNewAllContent = new byte[nNewHeight * nNewBMPRowByte + 1];
	if(NULL == pNewAllContent)
	{
		return false;
	}
	memset(pNewAllContent, 0, nNewHeight * nNewBMPRowByte + 1);

 	LONG nBmpRowByte = ((strBmpBitmap.biWidth*strBmpBitmap.biBitCount + 31)/8)/4*4;	 

	// 转存数据
	for (int row = 0 ; row < strBmpBitmap.biHeight; row ++ )
	{
		for(int col = 0; col < strBmpBitmap.biWidth; col ++)
		{
			if (pAllContent[row * nBmpRowByte + col / 8] & (0x01 << (7 - col % 8)))
			{
				pNewAllContent[(nNewHeight - col - 1) * nNewBMPRowByte + row / 8] |= 0x01 << (7 - row % 8);
			}	
		}
	}

	if(!openFile.Open(szFileName, CFile::modeCreate | CFile::modeWrite))
	{
		return false;
	}
	strBmpBitmap.biWidth = nNewWidth;
	strBmpBitmap.biHeight = nNewHeight;

	openFile.Write((void*)&strBmpHead, sizeof(strBmpHead));
	openFile.Write((void*)&strBmpBitmap, sizeof(strBmpBitmap));
	openFile.Write((void*)&bmprgb1, sizeof(bmprgb1));
	openFile.Write((void*)&bmprgb2, sizeof(bmprgb2));
	openFile.Write(pNewAllContent, nNewHeight * nNewBMPRowByte);

	openFile.Close();

	delete []pAllContent;
	pAllContent = NULL;
	delete []pNewAllContent;
	pNewAllContent = NULL;
	return true;
}

注意 

1、前原图的行、列 与新图的行列反转,位运算是也要对应。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用MFC代码将24位图转换为单色位图的示例: ``` // 定义24位图单色位图位图信息头 BITMAPINFOHEADER biSrc, biDst; // 读取24位图像素数据 BYTE* pSrcBits = (BYTE*)pSrcDib->GetBits(); // 计算24位图每个像素占用的字节数 int nSrcPitch = ((pSrcDib->GetWidth() * 24 + 31) & ~31) >> 3; // 计算单色位图每个像素占用的字节数 int nDstPitch = ((pSrcDib->GetWidth() + 31) & ~31) >> 3; // 分配单色位图像素数据空间 BYTE* pDstBits = new BYTE[nDstPitch * pSrcDib->GetHeight()]; // 将24位图转换为单色位图 for (int y = 0; y < pSrcDib->GetHeight(); y++) { for (int x = 0; x < pSrcDib->GetWidth(); x++) { // 获取24位图像素点的RGB值 BYTE r = pSrcBits[y * nSrcPitch + x * 3 + 2]; BYTE g = pSrcBits[y * nSrcPitch + x * 3 + 1]; BYTE b = pSrcBits[y * nSrcPitch + x * 3]; // 计算单色位图像素点的灰值 BYTE gray = (BYTE)((r * 30 + g * 59 + b * 11) / 100); // 设置单色位图像素点的值 if (gray > 128) { pDstBits[y * nDstPitch + x / 8] &= ~(1 << (7 - x % 8)); } else { pDstBits[y * nDstPitch + x / 8] |= (1 << (7 - x % 8)); } } } // 设置24位图单色位图位图信息头 biSrc.biSize = sizeof(BITMAPINFOHEADER); biSrc.biWidth = pSrcDib->GetWidth(); biSrc.biHeight = pSrcDib->GetHeight(); biSrc.biPlanes = 1; biSrc.biBitCount = 24; biSrc.biCompression = BI_RGB; biSrc.biSizeImage = nSrcPitch * pSrcDib->GetHeight(); biSrc.biXPelsPerMeter = 0; biSrc.biYPelsPerMeter = 0; biSrc.biClrUsed = 0; biSrc.biClrImportant = 0; biDst.biSize = sizeof(BITMAPINFOHEADER); biDst.biWidth = pSrcDib->GetWidth(); biDst.biHeight = pSrcDib->GetHeight(); biDst.biPlanes = 1; biDst.biBitCount = 1; biDst.biCompression = BI_RGB; biDst.biSizeImage = nDstPitch * pSrcDib->GetHeight(); biDst.biXPelsPerMeter = 0; biDst.biYPelsPerMeter = 0; biDst.biClrUsed = 0; biDst.biClrImportant = 0; // 创建单色位图DIB对象 CDib* pDstDib = new CDib(); pDstDib->CreateDib(&biDst, pDstBits); // 释放单色位图像素数据空间 delete[] pDstBits; ``` 该代码首先读取24位图像素数据,并计算出24位图单色位图每个像素占用的字节数。然后,使用双重循环遍历24位图的每个像素点,获取其RGB值,并计算出其灰值。最后,根据灰值设置单色位图像素点的值。最后,使用新的位图信息头和单色位图像素数据创建单色位图DIB对象。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值