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

📄 dibapi.cpp

📁 vc++数字图像处理 ,是一本很不错的介绍数字图像方面的书籍,这里有本书的全部源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	}	else	{		// 象素的大小		DWORD dwBmBitsSize;		// 大小为Width * Height		dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight;				// 计算出DIB真正的大小		dwDIBSize += dwBmBitsSize;		// 更新biSizeImage(很多BMP文件头中biSizeImage的值是错误的)		lpBI->biSizeImage = dwBmBitsSize;	}	// 计算文件大小:DIB大小+BITMAPFILEHEADER结构大小	bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);		// 两个保留字	bmfHdr.bfReserved1 = 0;	bmfHdr.bfReserved2 = 0;	// 计算偏移量bfOffBits,它的大小为Bitmap文件头大小+DIB头大小+颜色表大小	bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize											  + PaletteSize((LPSTR)lpBI);	// 尝试写文件	TRY	{		// 写文件头		file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));				// 写DIB头和象素		file.WriteHuge(lpBI, dwDIBSize);	}	CATCH (CFileException, e)	{		// 解除锁定		::GlobalUnlock((HGLOBAL) hDib);				// 抛出异常		THROW_LAST();	}	END_CATCH		// 解除锁定	::GlobalUnlock((HGLOBAL) hDib);		// 返回TRUE	return TRUE;}/************************************************************************* * * 函数名称: *   ReadDIBFile() * * 参数: *   CFile& file        - 要读取得文件文件CFile * * 返回值: *   HDIB               - 成功返回DIB的句柄,否则返回NULL。 * * 说明: *   该函数将指定的文件中的DIB对象读到指定的内存区域中。除BITMAPFILEHEADER * 外的内容都将被读入内存。 * *************************************************************************/HDIB WINAPI ReadDIBFile(CFile& file){	BITMAPFILEHEADER bmfHeader;	DWORD dwBitsSize;	HDIB hDIB;	LPSTR pDIB;	// 获取DIB(文件)长度(字节)	dwBitsSize = file.GetLength();	// 尝试读取DIB文件头	if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))	{		// 大小不对,返回NULL。		return NULL;	}	// 判断是否是DIB对象,检查头两个字节是否是"BM"	if (bmfHeader.bfType != DIB_HEADER_MARKER)	{		// 非DIB对象,返回NULL。		return NULL;	}	// 为DIB分配内存	hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);	if (hDIB == 0)	{		// 内存分配失败,返回NULL。		return NULL;	}		// 锁定	pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);	// 读象素	if (file.ReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=		dwBitsSize - sizeof(BITMAPFILEHEADER) )	{		// 大小不对。				// 解除锁定		::GlobalUnlock((HGLOBAL) hDIB);				// 释放内存		::GlobalFree((HGLOBAL) hDIB);				// 返回NULL。		return NULL;	}		// 解除锁定	::GlobalUnlock((HGLOBAL) hDIB);		// 返回DIB句柄	return hDIB;}/************************************************************************* * * 函数名称: *   DIBToPCX256() * * 参数: *   LPSTR lpDIB        - 指向DIB对象的指针 *   CFile& file        - 要保存的文件 * * 返回值: *   BOOL               - 成功返回True,否则返回False。 * * 说明: *   该函数将指定的256色DIB对象保存为256色PCX文件。 * *************************************************************************/BOOL WINAPI DIBToPCX256(LPSTR lpDIB, CFile& file){	// 循环变量	LONG	i;	LONG	j;		// DIB高度	WORD	wHeight;		// DIB宽度	WORD	wWidth;		// 中间变量	BYTE	bChar1;	BYTE	bChar2;		// 指向源图像象素的指针	BYTE *	lpSrc;		// 指向编码后图像数据的指针	BYTE *	lpDst;		// 图像每行的字节数	LONG	lLineBytes;		// 重复像素计数	int		iCount;		// 缓冲区已使用的字节数	DWORD	dwBuffUsed;		// 指向DIB象素指针	LPSTR   lpDIBBits;		// 获取DIB高度	wHeight = (WORD) DIBHeight(lpDIB);		// 获取DIB宽度	wWidth  = (WORD) DIBWidth(lpDIB);		// 找到DIB图像象素起始位置	lpDIBBits = FindDIBBits(lpDIB);		// 计算图像每行的字节数	lLineBytes = WIDTHBYTES(wWidth * 8);			//*************************************************************************	// PCX文件头	PCXHEADER pcxHdr;		// 给文件头赋值		// PCX标识码	pcxHdr.bManufacturer = 0x0A;		// PCX版本号	pcxHdr.bVersion = 5;		// PCX编码方式(1表示RLE编码)	pcxHdr.bEncoding = 1;		// 像素位数(256色为8位)	pcxHdr.bBpp = 8;		// 图像相对于屏幕的左上角X坐标(以像素为单位)	pcxHdr.wLeft = 0;		// 图像相对于屏幕的左上角Y坐标(以像素为单位)	pcxHdr.wTop = 0;		// 图像相对于屏幕的右下角X坐标(以像素为单位)	pcxHdr.wRight = wWidth - 1;		// 图像相对于屏幕的右下角Y坐标(以像素为单位)	pcxHdr.wBottom = wHeight - 1;		// 图像的水平分辨率	pcxHdr.wXResolution = wWidth;		// 图像的垂直分辨率	pcxHdr.wYResolution = wHeight;		// 调色板数据(对于256色PCX无意义,直接赋值为0)	for (i = 0; i < 48; i ++)	{		pcxHdr.bPalette[i] = 0;	}		// 保留域,设定为0。	pcxHdr.bReserved = 0;		// 图像色彩平面数目(对于256色PCX设定为1)。	pcxHdr.bPlanes = 1;		// 图像的宽度(字节为单位),必须为偶数。//	if ((wWidth & 1) == 0)//	{		pcxHdr.wLineBytes = wWidth;//	}//	else//	{//		pcxHdr.wLineBytes = wWidth + 1;//	}		// 图像调色板的类型,1表示彩色或者单色图像,2表示图像是灰度图。	pcxHdr.wPaletteType = 1;		// 制作该图像的屏幕宽度(像素为单位)	pcxHdr.wSrcWidth = 0;		// 制作该图像的屏幕高度(像素为单位)	pcxHdr.wSrcDepth = 0;		// 保留域,取值设定为0。	for (i = 0; i < 54; i ++)	{		pcxHdr.bFiller[i] = 0;	}		// 写入文件头	file.Write((LPSTR)&pcxHdr, sizeof(PCXHEADER));		//*******************************************************************************	// 开始编码		// 开辟一片缓冲区(2被原始图像大小)以保存编码结果	lpDst = new BYTE[wHeight * wWidth * 2];		// 指明当前已经用了多少缓冲区(字节数)	dwBuffUsed = 0;		// 每行	for (i = 0; i < wHeight; i++)	{		// 指向DIB第i行,第0个象素的指针		lpSrc = (BYTE *)lpDIBBits + lLineBytes * (wHeight - 1 - i);				// 给bChar1赋值		bChar1 = *lpSrc;				// 设置iCount为1		iCount = 1;				// 剩余列		for (j = 1; j < wWidth; j ++)		{			// 指向DIB第i行,第j个象素的指针			lpSrc++;						// 读取下一个像素			bChar2 = *lpSrc;						// 判断是否和bChar1相同并且iCount < 63			if ((bChar1 == bChar2) && (iCount < 63))			{				// 相同,计数加1				iCount ++;								// 继续读下一个			}			else			{				// 不同,或者iCount = 63								// 写入缓冲区				if ((iCount > 1) || (bChar1 >= 0xC0))				{					// 保存码长信息					lpDst[dwBuffUsed] = iCount | 0xC0;										// 保存bChar1					lpDst[dwBuffUsed + 1] = bChar1;										// 更新dwBuffUsed					dwBuffUsed += 2;				}				else				{					// 直接保存该值					lpDst[dwBuffUsed] = bChar1;										// 更新dwBuffUsed					dwBuffUsed ++;				}								// 重新给bChar1赋值				bChar1 = bChar2;								// 设置iCount为1				iCount = 1;			}		}				// 保存每行最后一部分编码		if ((iCount > 1) || (bChar1 >= 0xC0))		{			// 保存码长信息			lpDst[dwBuffUsed] = iCount | 0xC0;						// 保存bChar1			lpDst[dwBuffUsed + 1] = bChar1;						// 更新dwBuffUsed			dwBuffUsed += 2;		}		else		{			// 直接保存该值			lpDst[dwBuffUsed] = bChar1;						// 更新dwBuffUsed			dwBuffUsed ++;		}	}		// 写入编码结果	file.WriteHuge((LPSTR)lpDst, dwBuffUsed);		// 释放内存	delete lpDst;		//**************************************************************************	// 写入调色板信息		// 指向BITMAPINFO结构的指针(Win3.0)	LPBITMAPINFO lpbmi;		// 指向BITMAPCOREINFO结构的指针	LPBITMAPCOREINFO lpbmc;		// 表明是否是Win3.0 DIB的标记	BOOL bWinStyleDIB;		// 开辟一片缓冲区以保存调色板	lpDst = new BYTE[769];		// 调色板起始字节	* lpDst = 0x0C;		// 获取指向BITMAPINFO结构的指针(Win3.0)	lpbmi = (LPBITMAPINFO)lpDIB;		// 获取指向BITMAPCOREINFO结构的指针	lpbmc = (LPBITMAPCOREINFO)lpDIB;		// 判断是否是WIN3.0的DIB	bWinStyleDIB = IS_WIN30_DIB(lpDIB);		// 读取当前DIB调色板	for (i = 0; i < 256; i ++)	{		if (bWinStyleDIB)		{			// 读取DIB调色板红色分量			lpDst[i * 3 + 1] = lpbmi->bmiColors[i].rgbRed;						// 读取DIB调色板绿色分量			lpDst[i * 3 + 2] = lpbmi->bmiColors[i].rgbGreen;						// 读取DIB调色板蓝色分量			lpDst[i * 3 + 3] = lpbmi->bmiColors[i].rgbBlue;		}		else		{			// 读取DIB调色板红色分量			lpDst[i * 3 + 1] = lpbmc->bmciColors[i].rgbtRed;						// 读取DIB调色板绿色分量			lpDst[i * 3 + 2] = lpbmc->bmciColors[i].rgbtGreen;						// 读取DIB调色板蓝色分量			lpDst[i * 3 + 3] = lpbmc->bmciColors[i].rgbtBlue;		}	}		// 写入调色板信息	file.Write((LPSTR)lpDst, 769);		// 返回	return TRUE;}/************************************************************************* * * 函数名称: *   ReadPCX256() * * 参数: *   CFile& file        - 要读取的文件 * * 返回值: *   HDIB               - 成功返回DIB的句柄,否则返回NULL。 * * 说明: *   该函数将读取指定的256色PCX文件。将读取的结果保存在一个未压缩 * 编码的DIB对象中。 * *************************************************************************/HDIB WINAPI ReadPCX256(CFile& file){	// PCX文件头	PCXHEADER pcxHdr;		// DIB大小(字节数)	DWORD	dwDIBSize;		// DIB句柄	HDIB	hDIB;		// DIB指针	LPSTR	pDIB;		// 循环变量	LONG	i;	LONG	j;		// 重复像素计数	int		iCount;		// DIB高度	WORD	wHeight;		// DIB宽度	WORD	wWidth;		// 图像每行的字节数	LONG	lLineBytes;		// 中间变量	BYTE	bChar;		// 指向源图像象素的指针	BYTE *	lpSrc;		// 指向编码后图像数据的指针	BYTE *	lpDst;		// 临时指针	BYTE *	lpTemp;		// 尝试读取PCX文件头	if (file.Read((LPSTR)&pcxHdr, sizeof(PCXHEADER)) != sizeof(PCXHEADER))	{		// 大小不对,返回NULL。		return NULL;	}		// 判断是否是256色PCX文件,检查第一个字节是否是0x0A,	if ((pcxHdr.bManufacturer != 0x0A) || (pcxHdr.bBpp != 8) || (pcxHdr.bPlanes != 1))	{		// 非256色PCX文件,返回NULL。		return NULL;	}		// 获取图像高度	wHeight = pcxHdr.wBottom - pcxHdr.wTop + 1;		// 获取图像宽度	wWidth  = pcxHdr.wRight - pcxHdr.wLeft + 1;		// 计算图像每行的字节数	lLineBytes = WIDTHBYTES(wWidth * 8);		// 计算DIB长度(字节)	dwDIBSize = sizeof(BITMAPINFOHEADER) + 1024 + wHeight * lLineBytes;		// 为DIB分配内存	hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwDIBSize);	if (hDIB == 0)	{		// 内存分配失败,返回NULL。		return NULL;	}		// 锁定	pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);		// 指向BITMAPINFOHEADER的指针	LPBITMAPINFOHEADER lpBI;		// 赋值	lpBI = (LPBITMAPINFOHEADER) pDIB;		// 给lpBI成员赋值	lpBI->biSize = 40;	lpBI->biWidth = wWidth;	lpBI->biHeight = wHeight;	lpBI->biPlanes = 1;	lpBI->biBitCount = 8;	lpBI->biCompression = BI_RGB;	lpBI->biSizeImage = wHeight * lLineBytes;	lpBI->biXPelsPerMeter = pcxHdr.wXResolution;	lpBI->biYPelsPerMeter = pcxHdr.wYResolution;	lpBI->biClrUsed = 0;	lpBI->biClrImportant = 0;		// 分配内存以读取编码后的象素	lpSrc = new BYTE[file.GetLength() - sizeof(PCXHEADER) - 769];	lpTemp = lpSrc;		// 读取编码后的象素	if (file.ReadHuge(lpSrc, file.GetLength() - sizeof(PCXHEADER) - 769) !=		file.GetLength() - sizeof(PCXHEADER) - 769 )	{		// 大小不对。				// 解除锁定		::GlobalUnlock((HGLOBAL) hDIB);				// 释放内存		::GlobalFree((HGLOBAL) hDIB);				// 返回NULL。		return NULL;	}		// 计算DIB中像素位置	lpDst = (BYTE *) FindDIBBits(pDIB);		// 一行一行解码	for (j = 0; j <wHeight; j++)	{		i = 0;		while (i < wWidth)		{			// 读取一个字节			bChar = *lpTemp;			lpTemp++;						if ((bChar & 0xC0) == 0xC0)			{				// 行程				iCount = bChar & 0x3F;								// 读取下一个字节				bChar = *lpTemp;				lpTemp++;								// bChar重复iCount次保存				memset(&lpDst[(wHeight - j - 1) * lLineBytes + i], bChar, iCount);				// 已经读取像素的个数加iCount				i += iCount;			}			else			{				// 保存当前字节				lpDst[(wHeight - j - 1) * lLineBytes + i] = bChar;								// 已经读取像素的个数加1				i += 1;			}		}	}		// 释放内存	delete lpSrc;		//*************************************************************	// 调色板		// 读调色板标志位	file.Read(&bChar, 1);	if (bChar != 0x0C)	{		// 出错				// 解除锁定		::GlobalUnlock((HGLOBAL) hDIB);				// 释放内存		::GlobalFree((HGLOBAL) hDIB);				// 返回NULL。		return NULL;	}		// 分配内存以读取编码后的象素	lpSrc = new BYTE[768];		// 计算DIB中调色板的位置	lpDst = (BYTE *) pDIB + sizeof(BITMAPINFOHEADER);		// 读取调色板	if (file.Read(lpSrc, 768) != 768)	{		// 大小不对。				// 解除锁定		::GlobalUnlock((HGLOBAL) hDIB);				// 释放内存		::GlobalFree((HGLOBAL) hDIB);				// 返回NULL。		return NULL;	}		// 给调色板赋值	for (i = 0; i < 256; i++)	{		lpDst[i * 4] = lpSrc[i * 3 + 2];		lpDst[i * 4 + 1] = lpSrc[i * 3 + 1];		lpDst[i * 4 + 2] = lpSrc[i * 3];		lpDst[i * 4 + 3] = 0;	}		// 释放内存	delete lpSrc;		// 解除锁定	::GlobalUnlock((HGLOBAL) hDIB);		// 返回DIB句柄	return hDIB;}

⌨️ 快捷键说明

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