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

📄 ddb.cpp

📁 《Visual C++数字图像与图形处理》一书中编译通过的图像显示程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	if(pPE == NULL)return; 
	pPalette->GetPaletteEntries(0, 256, pPE); 
	
	for(int j = 0; j < 256; j++)
	{
		pRGBQuad[j].rgbRed = pPE[j].peRed; 
		pRGBQuad[j].rgbGreen = pPE[j].peGreen; 
		pRGBQuad[j].rgbBlue = pPE[j].peBlue; 
	}

	delete[] pPE; 
	delete pPalette; 

	//////////////////////////////////////////////////////
	//第三步, 填充与位图相关的结构

	//宽度字节数
	DWORD dwDibWidthBytes = ((w * 8 + 31) / 32) * 4; 
	//位图数据大小
	DWORD dwDibBitsSize = dwDibWidthBytes * h; 

	//计算整个Dib文件的大小dwFileSize
	DWORD dwFileSize = sizeof(BITMAPFILEHEADER) 
						 + sizeof(BITMAPINFOHEADER) 
						 + 256 * sizeof(RGBQUAD)
						 + dwDibBitsSize; 

	//计算位图信息到位图数据间的偏移量(字节)
	DWORD dwOffBits = sizeof(BITMAPFILEHEADER) 
						+ sizeof(BITMAPINFOHEADER) 
						+ 256 * sizeof(RGBQUAD); 

	//位图文件头结构和位图信息结构
	BITMAPFILEHEADER bmFileHeader; 
	BITMAPINFOHEADER bmInfo; 

	//填充BITMAPFILEHEADER结构
	bmFileHeader.bfType=0x4d42; 
	bmFileHeader.bfSize = dwFileSize; 
	bmFileHeader.bfReserved1 = 0; 
	bmFileHeader.bfReserved2 = 0;  
    bmFileHeader.bfOffBits = dwOffBits; 

	//填充BITMAPINFOHEADER结构

	bmInfo.biSize = sizeof(BITMAPINFOHEADER);     
	bmInfo.biWidth = w;     
	bmInfo.biHeight = h;     
	bmInfo.biPlanes = 1;  
	bmInfo.biBitCount = 8;     
	bmInfo.biCompression = 0;     
	bmInfo.biSizeImage = 0;  
	bmInfo.biXPelsPerMeter = 0;     
	bmInfo.biYPelsPerMeter = 0;     
	bmInfo.biClrUsed = 0;  
	bmInfo.biClrImportant = 0; 	

	//第四步, 写数据
	//////////////////////////////////////////////////////
	try
	{
		//	请创建自己的目录或获取当前目录:
		CFile file((LPCTSTR )pszDibFileName, CFile::modeCreate |
			CFile::modeReadWrite | CFile::shareExclusive); 

		//写入文件头和位图信息
		file.Write((LPSTR)&bmFileHeader, sizeof(BITMAPFILEHEADER)); 
		file.Write((LPSTR)&bmInfo, sizeof(BITMAPINFOHEADER)); 

		//写入数据
		file.Write((LPSTR)pRGBQuad, 256 * sizeof(RGBQUAD)); 
		
		delete[] pRGBQuad; 
		pRGBQuad = NULL; 

		//数据索引(行头)
		DWORD dwBaseIndex = (DWORD)(h - 1) * dwWidthBytes8; 

		UINT nZero =  dwDibWidthBytes - dwWidthBytes8; 
		BYTE abyZero[] =  {0, 0}; 
		
		for(int i = 0; i < h ; i++)
		{
			BYTE* pDibBits8 = pbyDdbBits8 + dwBaseIndex; 
			file.Write((LPSTR)pDibBits8,  dwWidthBytes8); 
			if(nZero > 0)file.Write((LPSTR)abyZero, 2); 
			dwBaseIndex -= dwWidthBytes8; 
		}//end i

		file.Close(); 
	}//end try
	catch(CFileException* e)
	{
		e->Delete(); 
	}

	if(pRGBQuad)delete[] pRGBQuad; 

	delete[] pbyDdbBits24; 
	delete[] pbyDdbBits8; 

	AfxGetApp()->EndWaitCursor(); 
}

//获取子区域的数据, 可以反复调用该函数, 
//获取24位格式的数据, 即任何格式的像素数据均被转化为24位格式.存储于lpbyBits24中
//存放顺序:蓝----绿----红
void CDdb::GetDdbDataTo24( int x, int y, int nWidth, int nHeight, LPBYTE lpbyBits24)
{
	ASSERT(lpbyBits24); 
	//首先进行参数合法性检测
	if((x > m_nWidth - 1) || (y > nHeight - 1))
	{
		AfxMessageBox("Cross the border!"); 
		return; 
	}
	//最后有效宽度和高度:w , h.
	LONG w = (LONG)min(nWidth, m_nWidth - x); 
	LONG h = (LONG)min(nHeight, m_nHeight - y); 

	//转换成24位后, 每行的大小和总的数据量
	DWORD dwWidthBytes24 =  ((w * 24 + 15) / 16) * 2; 
	
	//第二步, 将其转化为24位格式.

	switch(m_nBitCount)
	{
		case 8:
		{
			//为8位显示模式准备调色盘
			RGBQUAD* pRGBQuad = new RGBQUAD[256]; 
			if(pRGBQuad == NULL)return ; 
			//初始化为0
			memset(pRGBQuad, 0, 256 * sizeof(RGBQUAD)); 
			//创建表项
			GetSystemPaletteEntries(pRGBQuad); 

			//数据索引基数, 从上往下读
			DWORD dwBaseIndex = y * m_nDdbWidthBytes + x; 
			DWORD dwBase24 = 0; 
			for(LONG i = 0; i < h; i++)
			{
				//指向行头的指针, ddb.
				BYTE* pbyDdbRaw = m_pDdbData + dwBaseIndex; 

				//指向行头的指针, 24位.
				BYTE* pbyBits24Raw = lpbyBits24 + dwBase24; 

				for(LONG j = 0; j < w; j++)
				{
					BYTE byPixel = *(pbyDdbRaw++); 
					*(pbyBits24Raw++) = pRGBQuad[byPixel].rgbBlue; 
					*(pbyBits24Raw++) = pRGBQuad[byPixel].rgbGreen; 
					*(pbyBits24Raw++) = pRGBQuad[byPixel].rgbRed; 

				}//end j
				dwBaseIndex += m_nDdbWidthBytes; 
				dwBase24 += dwWidthBytes24; 
			}//end i
			delete[] pRGBQuad; 
			break; 		
		}
		case 24:
		{
			//每行数据个数(字节)
			DWORD dwLength = w * 3; 
			
			BYTE* pbyDdbRaw = m_pDdbData + y * m_nDdbWidthBytes + x + x + x; 
			//指向行头的指针, 24位.
			BYTE* pbyBits24Raw = lpbyBits24; 

			for(LONG i = 0; i < h; i++)
			{
				::CopyMemory(pbyBits24Raw, pbyDdbRaw, dwLength); 
				pbyDdbRaw += m_nDdbWidthBytes; 	//from
				pbyBits24Raw += dwWidthBytes24; 	//to
			}
			break; 		
		}//end case
		case 16:
		case 32:
		{
			//数据索引基数, 从上往下读
			DWORD dwBaseIndex = y * m_nDdbWidthBytes + ((m_nBitCount == 16) ? (x + x) : (4 * x)); 
			DWORD dwBase24 = 0; 
			for( LONG i = 0;  i < h; i++)
			{
				//指向行头的指针, ddb.
				BYTE* pbyDdbRaw = m_pDdbData + dwBaseIndex; 

				//从上往下
				DWORD dwBitsIndex24 = (DWORD)(i * dwWidthBytes24); 
				//指向行头的指针, 24位.
				BYTE* pbyBits24Raw = lpbyBits24 + dwBase24; 

				for(LONG j = 0; j < w; j++)
				{
					
					//处理16位
					if(m_nBitCount == 16)
					{
						//记录一个像素点的24位颜色值(16位和32位模式均被转化为24位)
						BYTE* pbyRGB = new BYTE[3]; 

						WORD* pwDdbData_16 = (WORD*)(pbyDdbRaw++); 
						GetRGB16(pbyRGB, pwDdbData_16); 
						pbyDdbRaw++; 

						//蓝--绿--红
						*pbyBits24Raw++ = pbyRGB[0]; 	//蓝色
						*pbyBits24Raw++ = pbyRGB[1]; 	//绿色
						*pbyBits24Raw++ = pbyRGB[2]; 	//红色
						delete[] pbyRGB; 
					}

					//处理32位
					if(m_nBitCount == 32)
					{
						//蓝--绿--红
						*pbyBits24Raw++ = *pbyDdbRaw++; 	//蓝色
						*pbyBits24Raw++ = *pbyDdbRaw++; 	//绿色
						*pbyBits24Raw++ = *pbyDdbRaw++; 	//红色
						pbyDdbRaw++; 
					}
				}//end j
				dwBaseIndex += m_nDdbWidthBytes; 
				dwBase24 += dwWidthBytes24; 
			}//end i
			break; 	
		}//end case
	}//end switch
}

//获取子区域的数据, 可以反复调用该函数, 
//获取32位格式的数据, 即任何格式的像素数据均被转化为32位格式.存储于lpbyBits32中
//颜色数据存放顺序:蓝--绿--红--**
void CDdb::GetDdbDataTo32( int x, int y, int nWidth, int nHeight, LPBYTE lpbyBits32)
{
	ASSERT(lpbyBits32); 
	//首先进行参数合法性检测
	if((x > m_nWidth - 1) || (y > nHeight - 1))
	{
		AfxMessageBox("Cross the border!"); 
		return; 
	}
	//最后有效宽度和高度:w , h.
	LONG w = (LONG)min(nWidth, m_nWidth - x); 
	LONG h = (LONG)min(nHeight, m_nHeight - y); 

	//转换成32位后, 每行的大小和总的数据量:字节
	DWORD dwWidthBytes32 =  w * 4; 
	
	//第二步, 将其转化为32位格式.

	switch(m_nBitCount)
	{
		case 8:
		{
			//为8位显示模式准备调色盘
			RGBQUAD* pRGBQuad = new RGBQUAD[256]; 
			if(pRGBQuad == NULL)return ; 
			//初始化为0
			memset(pRGBQuad, 0, 256 * sizeof(RGBQUAD)); 
			//创建表项
			GetSystemPaletteEntries(pRGBQuad); 

			//数据索引基数, 从上往下读
			//指向源数据
			DWORD dwBaseIndex = y * m_nDdbWidthBytes + x; 
			//指向32位数据
			DWORD dwBase32 = 0; 
			for(LONG i = 0; i < h; i++)
			{
				//指向行头的指针, ddb.
				BYTE* pbyDdbRaw = m_pDdbData + dwBaseIndex; 

				//指向行头的指针, 32位.
				BYTE* pbyBits32Raw = lpbyBits32 + dwBase32; 

				for(LONG j = 0; j < w; j++)
				{
					BYTE byPixel = *(pbyDdbRaw++); 

					//蓝--绿--红--**
					*(pbyBits32Raw++) = pRGBQuad[byPixel].rgbBlue; 
					*(pbyBits32Raw++) = pRGBQuad[byPixel].rgbGreen; 
					*(pbyBits32Raw++) = pRGBQuad[byPixel].rgbRed; 
					pbyBits32Raw++; 	
				}//end j

				dwBaseIndex += m_nDdbWidthBytes; 
				dwBase32 += dwWidthBytes32; 
			}//end i
			delete[] pRGBQuad; 
			break; 		
		}
		case 24:
		{
			//数据索引基数, 从上往下读
			DWORD dwBaseIndex = y * m_nDdbWidthBytes + x + x + x; 
			//指向32位数据
			DWORD dwBase32 = 0; 

			for(LONG i = 0; i < h; i++)
			{
				//指向行头的指针, ddb.
				BYTE* pbyDdbRaw = m_pDdbData + dwBaseIndex; 

				//指向行头的指针, 24位.
				BYTE* pbyBits32Raw = lpbyBits32 + dwBase32; 
				for(LONG j = 0; j < w; j++)
				{
					//蓝--绿--红--**
					*(pbyBits32Raw++) = *(pbyDdbRaw++); 	//b
					*(pbyBits32Raw++) = *(pbyDdbRaw++); 	//g
					*(pbyBits32Raw++) = *(pbyDdbRaw++); 	//r
					pbyBits32Raw++; 						//a

				}//end j
				dwBaseIndex += m_nDdbWidthBytes; 
				dwBase32 += dwWidthBytes32; 
			}
			break; 		
		}//end case
		case 16:
		{
			//数据索引基数, 从上往下读
			DWORD dwBaseIndex = y * m_nDdbWidthBytes + x + x; 
			//指向32位数据
			DWORD dwBase32 = 0; 
			for( LONG i = 0;  i < h; i++)
			{
				//指向行头的指针, ddb.
				BYTE* pbyDdbRaw = m_pDdbData + dwBaseIndex; 

				//从上往下
				DWORD dwBitsIndex32 = (DWORD)(i * dwWidthBytes32); 
				//指向行头的指针, 32位.
				BYTE* pbyBits32Raw = lpbyBits32 + dwBase32; 

				for(LONG j = 0; j < w; j++)
				{
					//处理16位
					//记录一个像素点的32位颜色值(16位和32位模式均被转化为24位)
					BYTE* pbyRGB = new BYTE[3]; 
					WORD* pwDdbData_16 = (WORD*)(pbyDdbRaw++); 
					GetRGB16(pbyRGB, pwDdbData_16); 
					pbyDdbRaw++; 

					//蓝--绿--红--**
					*pbyBits32Raw++ = pbyRGB[0]; 	//b
					*pbyBits32Raw++ = pbyRGB[1]; 	//g
					*pbyBits32Raw++ = pbyRGB[2]; 	//r
					pbyBits32Raw++; 					//a
					delete[] pbyRGB; 

				}//end j
				dwBaseIndex += m_nDdbWidthBytes; 
				dwBase32 += dwWidthBytes32; 
			}//end i
			break; 	
		}//end case 16
		case 32:
		{
			DWORD dwLength = w * 4; 
			//数据索引基数, 从上往下读
			DWORD dwBaseIndex = y * m_nDdbWidthBytes + 4 * x;  
			//指向行头的指针, ddb.
			BYTE* pbyDdbRaw = m_pDdbData + dwBaseIndex; 
			BYTE* pbyBits32Raw = lpbyBits32; 
			for( LONG i = 0;  i < h; i++)
			{
				::CopyMemory(pbyBits32Raw, pbyDdbRaw, dwLength); 
				pbyDdbRaw += m_nDdbWidthBytes; 
				pbyBits32Raw += dwWidthBytes32; 
			}//end i
			break; 	
		}//end case 32

	}//end switch
}



⌨️ 快捷键说明

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