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

📄 dibobject.cpp

📁 用C++实现的数字图像处理各个算法源代码 我精心整理的 很难的啊 希望可以给大家带来帮助
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		if( m_pLogPal != NULL ) delete [] m_pLogPal;
		m_pLogPal = CreatePaletteFromBitmap( nNumNewColors, pOldBits, m_nBits, m_nWidth, m_nHeight );
		}

	HGLOBAL hGlobal;
	DWORD dwSize;
	dwSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + nNumNewColors * sizeof( RGBQUAD ) + m_nHeight * nNewWidthBytes;
	hGlobal = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwSize );
	if( hGlobal == NULL ){
		::GlobalUnlock( m_hDib );
		return( FALSE );
		}

	pBuffer = (char *) ::GlobalLock( hGlobal );
	if( pBuffer == NULL ){
		::GlobalFree( hGlobal );
		::GlobalUnlock( m_hDib );
		return( FALSE );
		}

	pNewBFH = (BITMAPFILEHEADER *) pBuffer;
	pNewBIH = (BITMAPINFOHEADER *) &pBuffer[sizeof(BITMAPFILEHEADER)];
	pNewRGBPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
	*pNewBFH = *pOldBFH;
	*pNewBIH = *pOldBIH;
	int i, j = nNumNewColors;

	if( m_nBits < 16 && nNewBitsPerPixel < 16 ){
		for( i=0; i<j; i++ ) pNewRGBPalette[i] = pOldRGBPalette[i];
		}
	else if( m_nBits >= 16 ){
 		for( i=0; i<j; i++ ){
			pNewRGBPalette[i].rgbRed = m_pLogPal->palPalEntry[i].peRed;
			pNewRGBPalette[i].rgbGreen = m_pLogPal->palPalEntry[i].peGreen;
			pNewRGBPalette[i].rgbBlue = m_pLogPal->palPalEntry[i].peBlue;
			}
		}
	pNewBIH->biBitCount = nNewBitsPerPixel;
	pNewBIH->biSizeImage = nNewWidthBytes * m_nHeight;
	pNewBIH->biClrUsed = nNumNewColors;
	pNewBFH->bfSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + nNumNewColors * sizeof( RGBQUAD ) + pNewBIH->biSizeImage;
	pNewBFH->bfOffBits = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + nNumNewColors * sizeof( RGBQUAD );
	pNewBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumNewColors*sizeof(RGBQUAD)];
	m_nPaletteBytes = nNumNewColors * sizeof( RGBQUAD );

	for( int y=0; y<m_nHeight; y++ ){
		unsigned char ucRed, ucGreen, ucBlue;
		unsigned char *pSrc, *pDest;
		pSrc = pOldBits;
		pSrc += ( nOldWidthBytes * y );
		pDest = pNewBits;
		pDest += ( nNewWidthBytes * y );
		for( int x=0; x<m_nWidth; x++ ){
			switch( m_nBits ){
				case 1:
					if( pSrc[x/8] & ( 0x80 >> ( x & 7 ) ) )
						ucRed = ucGreen = ucBlue = 0xff;
					else
						ucRed = ucGreen = ucBlue = 0x00;
					break;
				case 4:
					if( !( x & 1 ) ){
						ucRed = pOldRGBPalette[pSrc[x/2]>>4].rgbRed;
						ucGreen = pOldRGBPalette[pSrc[x/2]>>4].rgbGreen;
						ucBlue = pOldRGBPalette[pSrc[x/2]>>4].rgbBlue;
						}
					else{
						ucRed = pOldRGBPalette[pSrc[x/2]&15].rgbRed;
						ucGreen = pOldRGBPalette[pSrc[x/2]&15].rgbGreen;
						ucBlue = pOldRGBPalette[pSrc[x/2]&15].rgbBlue;
						}
					break;
				case 8:
					ucRed = pOldRGBPalette[pSrc[x]].rgbRed;
					ucGreen = pOldRGBPalette[pSrc[x]].rgbGreen;
					ucBlue = pOldRGBPalette[pSrc[x]].rgbBlue;
					break;
				case 16:
					GETRGB555( ucRed, ucGreen, ucBlue, &pSrc[x*2] );
					break;
				case 24:
					ucRed = pSrc[x*3+2];
					ucGreen = pSrc[x*3+1];
					ucBlue = pSrc[x*3];
					break;
				case 32:
					GETRGB888( ucRed, ucGreen, ucBlue, &pSrc[x*4] );
					break;
				}

			switch( nNewBitsPerPixel ){
				case 1:
					if( !( x & 7 ) ) pDest[x/8] = 0;
					pDest[x/8] |= (unsigned char) GetNearestIndex( ucRed, ucGreen, ucBlue, pNewRGBPalette, nNumNewColors ) << ( x & 7 );
					break;
				case 4:
					if( !( x & 1 ) )
						pDest[x/2] = (unsigned char) GetNearestIndex( ucRed, ucGreen, ucBlue, pNewRGBPalette, nNumNewColors ) << 4;
					else
						pDest[x/2] |= (unsigned char) GetNearestIndex( ucRed, ucGreen, ucBlue, pNewRGBPalette, nNumNewColors );
					break;
				case 8:
					pDest[x] = (unsigned char) GetNearestIndex( ucRed, ucGreen, ucBlue, pNewRGBPalette, nNumNewColors );
					break;
				case 16:
					PUTRGB555( ucRed, ucGreen, ucBlue, &pDest[x*2] );
					break;
				case 24:
					pDest[x*3+2] = ucRed;
					pDest[x*3+1] = ucGreen;
					pDest[x*3] = ucBlue;
					break;
				case 32:
					PUTRGB888( ucRed, ucGreen, ucBlue, &pDest[x*4] );
					break;
				}
			}
		}

	::GlobalUnlock( m_hDib );
	::GlobalFree( m_hDib );
	::GlobalUnlock( hGlobal );
	m_hDib = hGlobal;

	ProcessImageHeader();

	return( TRUE );

}

////////////////////////////////////////////////////////////////////////
//LOGPALETTE CreatePaletteFromBitmap()		    
//----------------------------------------------------------------------
//基本功能:从当前CDibObject位图对象中创建逻辑调色板。
//----------------------------------------------------------------------
//参数说明:int nNumColors			颜色数
//			unsigned char *pBits	位图数据指针
//			int nBits				颜色位数
//			int nWidth				图像宽度
//			int nHeight				图像高度
//----------------------------------------------------------------------
//返 回 值:LOGPALETTE	逻辑调色板指针
////////////////////////////////////////////////////////////////////////
LOGPALETTE *CDibObject::CreatePaletteFromBitmap(int nNumColors, 
												unsigned char *pBits, int nBits, 
												int nWidth, int nHeight )
{

	RGBQUAD *pRGBPalette;
	if( nBits != 8 && m_nPaletteCreationType == POPULARITY_PALETTE ) pRGBPalette = MakePopularityPalette( nNumColors, pBits, nBits, nWidth, nHeight );
	else if( nBits != 8 && m_nPaletteCreationType == MEDIAN_CUT_PALETTE ) pRGBPalette = MakeMedianCutPalette( nNumColors, pBits, nBits, nWidth, nHeight );
	else if( m_nPaletteCreationType == FIXED_PALETTE ) pRGBPalette = MakeFixedPalette( nNumColors );
	if( pRGBPalette == NULL ) return( NULL );

	LOGPALETTE *pLogPal = CreateLogPalette( pRGBPalette, nNumColors );

	delete [] pRGBPalette;

	return( pLogPal );

}

////////////////////////////////////////////////////////////////////////
//void SetPaletteCreationType( int nType )		    
//----------------------------------------------------------------------
//基本功能:当希望通过颜色还原得到一幅具有调色板的图像时,本函数负责设置
//			调色板的创建类型。可以设置如下:
//			#define POPULARITY_PALETTE	0
//			#define MEDIAN_CUT_PALETTE	1
//			#define FIXED_PALETTE		2
//----------------------------------------------------------------------
//参数说明:int nType
//----------------------------------------------------------------------
//返 回 值:无
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
void CDibObject::SetPaletteCreationType( int nType )
{

	m_nPaletteCreationType = nType;

}

////////////////////////////////////////////////////////////////////////
//int GetPaletteCreationType( void )		    
//----------------------------------------------------------------------
//基本功能:本函数返回用于下一次颜色还原操作的调色板类型。
//----------------------------------------------------------------------
//参数说明:无
//----------------------------------------------------------------------
//返 回 值:int nPaletteCreationType
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
int CDibObject::GetPaletteCreationType( void )
{

	return( m_nPaletteCreationType );

}

RGBQUAD *CDibObject::MakePopularityPalette( int nNumColors, unsigned char *pBits, int nBits, int nWidth, int nHeight )
{
	RGBQUAD *pRGBQuad = new RGBQUAD[nNumColors];
	if( pRGBQuad == NULL ) return( MakeFixedPalette( nNumColors ) );
	memset( pRGBQuad, 0, nNumColors * sizeof( RGBQUAD ) );

	BYTE ColMap[256][3];
	if( !Popularity( pBits, nBits, nWidth, nHeight, ColMap ) ){
		delete [] pRGBQuad;
		return( MakeFixedPalette( nNumColors ) );
		}

	for( int i=0; i<nNumColors; i++ ){
		pRGBQuad[i].rgbRed = ColMap[i][0];
		pRGBQuad[i].rgbGreen = ColMap[i][1];
		pRGBQuad[i].rgbBlue = ColMap[i][2];
		}

	return( pRGBQuad );

}

RGBQUAD *CDibObject::MakeMedianCutPalette( int nNumColors, unsigned char *pBits, int nBits, int nWidth, int nHeight )
{
	RGBQUAD *pRGBQuad = new RGBQUAD[nNumColors];
	if( pRGBQuad == NULL ) return( MakeFixedPalette( nNumColors ) );
	memset( pRGBQuad, 0, nNumColors * sizeof( RGBQUAD ) );

	BYTE ColMap[256][3];
	WORD *Hist = new WORD[32768];
	if( Hist == NULL ){
		delete [] pRGBQuad;
		return( MakeFixedPalette( nNumColors ) );
		}
	memset( Hist, 0, 32768 * sizeof( WORD ) );

	int nWidthBytes = WidthBytes( nBits, nWidth );

	for( int y=0; y<nHeight; y++ ){
		unsigned char *pData = pBits;
		unsigned char ucRed, ucGreen, ucBlue;
		WORD color;
		pData += ( y * nWidthBytes );
		for( int x=0; x<nWidth; x++ ){
			switch( nBits ){
				case 16:
					GETRGB555( ucRed, ucGreen, ucBlue, &pData[x*2] );
					break;
				case 24:
					ucRed = pData[x*3+2];
					ucGreen = pData[x*3+1];
					ucBlue = pData[x*3];
					break;
				case 32:
					GETRGB888( ucRed, ucGreen, ucBlue, &pData[x*4] );
					break;
				}
			color = _RGB( ucRed, ucGreen, ucBlue );
			if( Hist[color] < 65535 ) Hist[color]++;
			}
		}

	MedianCut( Hist, ColMap, (int) 256 );
	for( int i=0; i<nNumColors; i++ ){
		pRGBQuad[i].rgbRed = ColMap[i][0];
		pRGBQuad[i].rgbGreen = ColMap[i][1];
		pRGBQuad[i].rgbBlue = ColMap[i][2];
		}
	delete [] Hist;

	return( pRGBQuad );

}

RGBQUAD *CDibObject::MakeFixedPalette( int nNumColors )
{
	RGBQUAD *pRGBQuad = new RGBQUAD[nNumColors];
	if( pRGBQuad == NULL ) return( NULL );

	static int colors[] = {
		255, 255, 255,
		0, 0, 0,
		255, 0, 0,
		0, 0, 255,
		0, 255, 0,
		150, 150, 150,
		255, 255, 0,
		0, 150, 150,
		150, 0, 150,
		150, 150, 0,
		0, 255, 255,
		255, 0, 255,
		255, 120, 120,
		120, 255, 120,
		120, 120, 255,
		90, 90, 90 };

	int nSteps = ( ( nNumColors + 15 ) / 16 );

	for( int i=0; i<nSteps; i++ ){
		for( int j=0; j<16; j++ ){
			if( i * 16 + j < nNumColors ){
				int r, g, b;
				r = colors[j*3];
				g = colors[j*3+1];
				b = colors[j*3+2];
				r = ( ( nSteps - i ) * r ) / nSteps;
				g = ( ( nSteps - i ) * g ) / nSteps;
				b = ( ( nSteps - i ) * b ) / nSteps;
				pRGBQuad[i*16+j].rgbRed = (unsigned char) r;
				pRGBQuad[i*16+j].rgbGreen = (unsigned char) g;
				pRGBQuad[i*16+j].rgbBlue = (unsigned char) b;
				}
			}
		}

	return( pRGBQuad );

}

//得到调色板字节数
int CDibObject::GetPaletteBytes( void )
{

	return( m_nPaletteBytes );

}

////////////////////////////////////////////////////////////////////////
//HGLOBALBOOL GetDib( void )	    
//----------------------------------------------------------------------
//基本功能:本函数返回当前载入的图像Dib句柄。
//----------------------------------------------------------------------
//参数说明:无
//----------------------------------------------------------------------
//返 回 值:HGLOBALBOOL hDib
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
HGLOBAL CDibObject::GetDib( void )
{

	return( m_hDib );

}

////////////////////////////////////////////////////////////////////////
//CPalette GetPalette( void )	    
//----------------------------------------------------------------------
//基本功能:本函数返回一个指向CPalette对象的指针。
//----------------------------------------------------------------------
//参数说明:无
//----------------------------------------------------------------------
//返 回 值:CPalette *Palette
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
CPalette *CDibObject::GetPalette( void )
{

	return( &m_Palette );

}

//得到逻辑调色板
LOGPALETTE *CDibObject::GetLogPal( void )
{

	return( m_pLogPal );

}

void CDibObject::ProcImgHead()
{
	ProcessImageHeader();
}

char * CDibObject::GetImageName()
{
	return( m_pszFilename );
}

⌨️ 快捷键说明

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