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

📄 dib.cpp

📁 利用一组样本之间的相关性
💻 CPP
📖 第 1 页 / 共 4 页
字号:
 *   无
 *
 * \返回值:
 *   DWORD				- 返回调色板的尺寸
 *
 * \说明:
 *   该函数计算机调色板所需的尺寸
 *
 ************************************************************************
 */
WORD CDib::PaletteSize()
{
	// 临时变量
	WORD	       NumColors;
	LPBITMAPINFOHEADER lpbi=m_lpBMIH;

	// 如果biClrUsed为零,且图象象素位数小于8,则计算调色板用到的表项数
	NumColors = 	((lpbi)->biClrUsed == 0 && (lpbi)->biBitCount <= 8 \
                                    ? (int)(1 << (int)(lpbi)->biBitCount)\
                                    : (int)(lpbi)->biClrUsed);

	// 根据颜色表示的字节数计算调色板的尺寸
	if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
		return NumColors * sizeof(RGBTRIPLE);
	else 
		return NumColors * sizeof(RGBQUAD);

}


/*************************************************************************
 *
 * \函数名称:
 *   IsEmpty()
 *
 * \输入参数:
 *   无
 *
 * \返回值:
 *   BOOL				- 如果信息头和图象数据为空,则返回TRUE
 *
 * \说明:
 *   判断信息头和图象数据是否为空
 *
 ************************************************************************
 */
BOOL CDib::IsEmpty()
{

	if(	m_lpBMIH == NULL&&m_lpImage == NULL)
		return TRUE;
	else
		return FALSE;

}


/*************************************************************************
 *
 * \函数名称:
 *   GetDibSaveDim()
 *
 * \输入参数:
 *   无
 *
 * \返回值:
 *   CSize			- DIB实际存储的高度和宽度
 *
 * \说明:
 *   该函数函数用来得到dib的实际存储宽度(DWORD对齐)
 *
 ************************************************************************
 */

CSize CDib::GetDibSaveDim()
{
	CSize sizeSaveDim;
	sizeSaveDim.cx	= ( m_lpBMIH->biWidth * m_lpBMIH->biBitCount + 31)/32 * 4;
	sizeSaveDim.cy	= m_lpBMIH->biHeight; 
	return sizeSaveDim;

}


/*************************************************************************
 *
 * \函数名称:
 *   GetPixelOffset()
 *
 * \输入参数:
 *   int	x		- 象素在X轴的坐标
 *   int	y		- 象素在Y轴的坐标
 *
 * \返回值:
 *   int			- 返回象素在图象数据块中的真实地址
 *
 * \说明:
 *   该函数得到坐标为(x,y)的象素点的真实地址。由于DIB结构中对图象数据排列的
 *   方式为从下到上,从左到右的,所以需要进行转换。
 *
 ************************************************************************
 */
LONG CDib::GetPixelOffset(int x, int y)
{
	CSize sizeSaveDim;
	sizeSaveDim = GetDibSaveDim();

//	LONG lOffset = (LONG) (sizeSaveDim.cy - y - 1) * sizeSaveDim.cx +
//		x  / (8 / m_lpBMIH->biBitCount);
	LONG lOffset = (LONG) (sizeSaveDim.cy - y - 1) * sizeSaveDim.cx +
		x * m_lpBMIH->biBitCount/8;
	//如果m_lpBMIH->biBitCount>8,除数为零,会报错
	return lOffset;
}


/*************************************************************************
 *
 * \函数名称:
 *   GetPixel()
 *
 * \输入参数:
 *   int	x		- 象素在X轴的坐标
 *   int	y		- 象素在Y轴的坐标
 *
 * \返回值:
 *   RGBQUAD			- 返回DIB在该点真实的颜色
 *
 * \说明:
 *   该函数得到DIB图象在该点真实的颜色。
 *   (函数有问题,已经修改了几个地方,别的还不清楚改动是否正确,需要验证)
 ************************************************************************
 */
RGBQUAD CDib::GetPixel(int x, int y)
{
	// 颜色结构
	RGBQUAD cColor;
	
	// 根据每象素比特数得到此点的象素值
	switch (m_lpBMIH->biBitCount)
	{
		case 1 :
			//if (1<<(7-x%8) & *(LPBYTE)(m_lpImage+GetPixelOffset(x, y)))
			if (1<<(7-x%8) & GetPixelOffset(x, y))
			{			
				cColor.rgbBlue  = 255;
				cColor.rgbGreen = 255;
				cColor.rgbRed   = 255;
				cColor.rgbReserved = 0;
			}
			else
			{			
				cColor.rgbBlue  = 0;
				cColor.rgbGreen = 0;
				cColor.rgbRed   = 0;	
				cColor.rgbReserved = 0;
			}
			break;
		case 4 :	
			{
				//int nIndex = (*(LPBYTE)(m_lpImage+GetPixelOffset(x, y)) & 
				//			   (x%2 ? 0x0f : 0xf0)) >> (x%2 ? 0 : 4);
				int nIndex = ((GetPixelOffset(x, y)) & 
							   (x%2 ? 0x0f : 0xf0)) >> (x%2 ? 0 : 4);
				LPRGBQUAD pDibQuad = (LPRGBQUAD) (m_lpvColorTable) + nIndex;
				cColor.rgbBlue  = pDibQuad->rgbBlue;
				cColor.rgbGreen = pDibQuad->rgbGreen;
				cColor.rgbRed   = pDibQuad->rgbRed;
				cColor.rgbReserved = 0;
			}
					break;
		case 8 :	
			{
				//int nIndex = *(BYTE*)(m_lpImage+GetPixelOffset(x, y));//???
				int nIndex = GetPixelOffset(x, y);
				LPRGBQUAD pDibQuad = (LPRGBQUAD) (m_lpvColorTable) + m_lpImage[nIndex];//nIndex/3;
				cColor.rgbBlue  = pDibQuad->rgbBlue;
				cColor.rgbGreen = pDibQuad->rgbGreen;
				cColor.rgbRed   = pDibQuad->rgbRed;
				cColor.rgbReserved = 0;

				//针对8位的灰度图象,特例
				//cColor.rgbRed=cColor.rgbGreen=cColor.rgbBlue=pDibQuad->rgbBlue;//m_lpImage[pDibQuad];
                //cColor.rgbReserved = 0;	
			}
					break;
		default:
				//int nIndex = *(BYTE*)(m_lpImage+GetPixelOffset(x, y));					
				int nIndex = GetPixelOffset(x,y);
				cColor.rgbRed   = m_lpImage[nIndex];
				cColor.rgbGreen = m_lpImage[nIndex + 1];
				cColor.rgbBlue  = m_lpImage[nIndex + 2];
				cColor.rgbReserved = 0;	
				break;
	}

	// 返回颜色结构
	return cColor;
}


//---------------------------------------
// 图像缩放
// 0.25 <= zoom <= 4;
// 最后一条边界好像还没有做对 ?
//---------------------------------------
CDib* CDib::Resize(float zoom)
{

	if ( 0.25 > zoom || zoom > 4) {
		AfxMessageBox("zoom out of bound", MB_OK);
		return NULL;
	}

	CSize size = this->GetDimensions();

	DWORD Wold = (DWORD)size.cx;
	DWORD Hold = (DWORD)size.cy;

	DWORD Wnew = (DWORD)(size.cx * zoom);
	DWORD Hnew = (DWORD)(size.cy * zoom);
	CSize newSize;
	newSize.cx = Wnew;
	newSize.cy = Hnew;

	CDib* newIm = new CDib(newSize, 24);
	newIm->ComputeMetrics();
	newIm->m_lpImage = (LPBYTE) new char[newIm->m_dwSizeImage];

	LPBYTE lpold = this->m_lpImage;
	LPBYTE lpnew = newIm->m_lpImage;

	int lenold = this->GetDibSaveDim().cx;
	int lennew = newIm->GetDibSaveDim().cx;

	DWORD h0, w0, h1, w1;
	float h01, w01;
	float zoom_1 = 1/zoom;

	for(DWORD h=0; h<Hnew; h++)
		for(DWORD w=0; w<Wnew; w++)
		{
			// bilinear interpolation
			h01 = (h*zoom_1);
			h0 = (DWORD)h01;
			h1 = h0 + 1;
			w01 = (w*zoom_1);
			w0 = (DWORD)w01;
			w1 = w0 + 1;

			float ratio_w = w01-w0;
			float ratio_h = h01-h0;

			if( (w0>=0) && (w1<Wold) && (h0>=0) && (h1<Hold) )
			{

				*(lpnew + lennew*h + w*3+2) = (unsigned char)( (1-ratio_h) * (*(lpold + lenold*h0 + w0*3+2)*(1-ratio_w) 
													+ *(lpold + lenold*h0 + w1*3+2)*(ratio_w))
													+(ratio_h) * (*(lpold + lenold*h1 + w0*3+2)*(1-ratio_w) 
													+ *(lpold + lenold*h1 + w1*3+2)*(ratio_w)) );
				*(lpnew + lennew*h + w*3+1) = (unsigned char)( (1-ratio_h) * (*(lpold + lenold*h0 + w0*3+1)*(1-ratio_w) 
													+ *(lpold + lenold*h0 + w1*3+1)*(ratio_w))
													+(ratio_h) * (*(lpold + lenold*h1 + w0*3+1)*(1-ratio_w) 
													+ *(lpold + lenold*h1 + w1*3+1)*(ratio_w)) );
				*(lpnew + lennew*h + w*3) = (unsigned char)( (1-ratio_h) * (*(lpold + lenold*h0 + w0*3)*(1-ratio_w) 
													+ *(lpold + lenold*h0 + w1*3)*(ratio_w))
													+(ratio_h) * (*(lpold + lenold*h1 + w0*3)*(1-ratio_w) 
													+ *(lpold + lenold*h1 + w1*3)*(ratio_w)) );
				
			}

			if( (w1 >= Wold) || (h1 >= Hold) )
			{

				*(lpnew + lennew*h + w*3+2) = (unsigned char)( (1-ratio_h) * (*(lpold + lenold*h0 + w0*3+2)*(1-ratio_w) 
													+ *(lpold + lenold*h0 + min(w1,Wold-1)*3+2)*(ratio_w))
													+(ratio_h) * (*(lpold + lenold*min(h1,Hold-1) + w0*3+2)*(1-ratio_w) 
													+ *(lpold + lenold*min(h1,Hold-1) + min(w1,Wold-1)*3+2)*(ratio_w)) );
				*(lpnew + lennew*h + w*3+1) = (unsigned char)( (1-ratio_h) * (*(lpold + lenold*h0 + w0*3+1)*(1-ratio_w) 
													+ *(lpold + lenold*h0 + min(w1,Wold-1)*3+1)*(ratio_w))
													+(ratio_h) * (*(lpold + lenold*min(h1,Hold-1) + w0*3+1)*(1-ratio_w) 
													+ *(lpold + lenold*min(h1,Hold-1) + min(w1,Wold-1)*3+1)*(ratio_w)) );
				*(lpnew + lennew*h + w*3) = (unsigned char)( (1-ratio_h) * (*(lpold + lenold*h0 + w0*3)*(1-ratio_w) 
													+ *(lpold + lenold*h0 + min(w1,Wold-1)*3)*(ratio_w))
													+(ratio_h) * (*(lpold + lenold*min(h1,Hold-1) + w0*3)*(1-ratio_w) 
													+ *(lpold + lenold*min(h1,Hold-1) + min(w1,Wold-1)*3)*(ratio_w)) );
			}

		}
//

		
	return newIm;
}

//
// 取直方图,mode 为方式,
// mode = 0 为 RGB 模式
// mode = 1 为 Gray 模式 
// mode = 2 为 HSV 模式
//
//  暂时只支持 Gray 模式
//
float* CDib::GetHist(int mode)
{
	if (mode!=1) return NULL;

	CSize size;
	size = GetDimensions();
	int length = GetDibSaveDim().cx;

	int* hist = new int[256];
	for (int j=0; j<256; j++)
		hist[j] = 0;

	byte R,G,B,Gray;
	for(j=0; j<size.cy; j++)
		for( int i=0; i<size.cx; i++)
		{
			R=*(m_lpImage+length*(size.cy-1-j)+i*3+2);
			G=*(m_lpImage+length*(size.cy-1-j)+i*3+1);
			B=*(m_lpImage+length*(size.cy-1-j)+i*3);
			Gray = unsigned char(0.11 * B + 0.59 * G + 0.30 * R);
			hist[Gray] = hist[Gray] + 1;
		}

	float* reslt = new float[256];
	for (j=0; j<256; j++)
		reslt[j] = hist[j]/(float)(size.cx * size.cy);

	return reslt;
}

//构造函数,根据源Dib得到新Dib
//用于开辟一块新的位图空间
CDib::CDib(CDib *pBMP)
{
	m_hFile      = NULL;
	m_hBitmap    = NULL;
	m_hPalette   = NULL;
	m_nBmihAlloc = m_nImageAlloc = noAlloc;
	Empty();

	// 根据象素位数计算调色板尺寸
	ComputePaletteSize(pBMP->m_lpBMIH->biBitCount);

	// 分配DIB信息头和调色板的内存
	m_lpBMIH = (LPBITMAPINFOHEADER) new 
		char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries];

	// 设置信息头内存分配状态
	m_nBmihAlloc = crtAlloc;

	// 设置信息头中的信息
	m_lpBMIH->biSize	= sizeof(BITMAPINFOHEADER);
	m_lpBMIH->biWidth	= pBMP->m_lpBMIH->biWidth;
	m_lpBMIH->biHeight	= pBMP->m_lpBMIH->biHeight;
	m_lpBMIH->biPlanes	= 1;
	m_lpBMIH->biBitCount	= pBMP->m_lpBMIH->biBitCount;
	m_lpBMIH->biCompression = BI_RGB;
	m_lpBMIH->biSizeImage	= 0;
	m_lpBMIH->biXPelsPerMeter = 0;
	m_lpBMIH->biYPelsPerMeter = 0;
	m_lpBMIH->biClrUsed	= m_nColorTableEntries;
	m_lpBMIH->biClrImportant= m_nColorTableEntries;

	// 计算图象数据内存的大小,并设置此DIB的调色板的指针
	ComputeMetrics();

	// 将此DIB的调色板初始化为0
	memset(m_lpvColorTable, 0, sizeof(RGBQUAD) * m_nColorTableEntries);

	if(pBMP->m_lpBMIH->biBitCount==8)
	{
		RGBQUAD * pPal;
		pPal = (RGBQUAD *)m_lpvColorTable;
		for (int i = 0; i < m_nColorTableEntries; i++)
		{			
			pPal[i].rgbBlue =
			pPal[i].rgbGreen =
			pPal[i].rgbRed = i;
		}
	}

	// 暂时不分配图象数据内存
	m_lpImage = pBMP->m_lpImage; 
}

BOOL CDib::ReadDIBFile(CString szFileName)
{
	// 释放已经分配的内存
	Empty();

//	CFile *pFile = NULL;
//	pFile=new CFile;

	CFile *pFile=new CFile;
	CFileException ex;
	pFile->Open(szFileName,CFile::modeRead | CFile::shareDenyWrite,&ex);
	// 临时存放信息的变量
	int nCount, nSize;
	BITMAPFILEHEADER bmfh;

	// 进行读操作
	try 
	{
		// 读取文件头
		nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
		if(nCount != sizeof(BITMAPFILEHEADER)) {
			throw new CException;
		}

		// 如果文件类型部位"BM",则返回并进行相应错误处理
		if(bmfh.bfType != 0x4d42) 
		{
			char filename[256];	
			GetTempPath(256, filename);
			strcat(filename, pFile->GetFileName());
			FILE *tmp;
			tmp = fopen(filename, "wb");
			fwrite(&bmfh, sizeof(BITMAPFILEHEADER), 1, tmp);
			char buf[8192];
			int len;

			len = pFile->Read(buf, 8192);
			while(len!=0)
			{
				fwrite(buf, len, 1, tmp);
				len = pFile->Read(buf, 8192);
			}
			fclose(tmp);
		}
		else
		{
			// 计算信息头加上调色板的大小,并分配相应的内存
			nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
			m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];
			m_nBmihAlloc = m_nImageAlloc = crtAlloc;

			// 读取信息头和调色板
			nCount = pFile->Read(m_lpBMIH, nSize); 

			// 计算图象数据大小并设置调色板指针
			ComputeMetrics();

			// 计算调色板的表项数
			ComputePaletteSize(m_lpBMIH->biBitCount);

			// 如果DIB中存在调色板,则创建一个Windows调色板
			MakePalette();

			// 分配图象数据内存,并从文件中读取图象数据
			m_lpImage = (LPBYTE)new char[m_dwSizeImage];
			nCount = pFile->Read(m_lpImage, m_dwSizeImage); 
		}
	}

	// 错误处理
	catch(CException* pe) 
	{
		AfxMessageBox("Read error");
		pe->Delete();
		return FALSE;
	}

	pSourceFile = pFile->Duplicate();

	// 返回
	return TRUE;
}

⌨️ 快捷键说明

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