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

📄 imageobject.cpp

📁 分水岭算法
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	{
		if( ucRed > pRGBPalette[ i ].rgbRed )
			dwRed = ( DWORD )( pRGBPalette[ i ].rgbRed - ucRed );
		else
			dwRed = ( DWORD )( ucRed - pRGBPalette[ i ].rgbRed );
		if( ucGreen > pRGBPalette[ i ].rgbGreen )
			dwGreen = ( DWORD )( pRGBPalette[ i ].rgbGreen - ucGreen );
		else
			dwGreen = ( DWORD )( ucGreen - pRGBPalette[ i ].rgbGreen );
		if( ucBlue > pRGBPalette[ i ].rgbBlue )
			dwBlue = ( DWORD )( pRGBPalette[ i ].rgbBlue - ucBlue );
		else
			dwBlue = ( DWORD )( ucBlue - pRGBPalette[ i ].rgbBlue );
		NewDiff = ( dwRed * dwRed ) + ( dwGreen * dwGreen ) + ( dwBlue * dwBlue );
		if( NewDiff < Diff )
		{
			if( NewDiff <= 1 ) 
				return( i );
			Diff = NewDiff;
			Index = i;
		}
	}
	return( Index );
}

void CImageObject::CreatePaletteFromDIB( RGBQUAD *pRGBPalette, int nColors )
{
	if( pRGBPalette != NULL )
	{
		LOGPALETTE *pPalette;
		pPalette = CreateLogPalette( pRGBPalette, nColors );
		if( pPalette != NULL )
		{
			m_Palette.CreatePalette( pPalette );
			delete[] pPalette;
		}
		else
			m_nLastError = GL_LOGICAL_PALETTE_CREATION_ERROR;
	}
}

LOGPALETTE *CImageObject::CreatePaletteFromBitmap( int nColors, unsigned char *pBits, int nBits, int nWidth, int nHeight )
{
	RGBQUAD *pRGBPalette;
	if( nBits != 8 && m_nPaletteCreationType == JGPT_POPULARITY_PALETTE )
		pRGBPalette = GeneratePopularityPalette( nColors, pBits, nBits, nWidth, nHeight );
	else if( nBits != 8 && m_nPaletteCreationType == JGPT_MEDIAN_CUT_PALETTE )
		pRGBPalette = GenerateMedianCutPalette( nColors, pBits, nBits, nWidth, nHeight );
	else if( m_nPaletteCreationType == JGPT_FIXED_PALETTE )
		pRGBPalette = GenerateFixedPalette( nColors );
	if( pRGBPalette == NULL )
		return( NULL );
	LOGPALETTE *pLogPalette = CreateLogPalette( pRGBPalette, nColors );
	delete[] pRGBPalette;
	return( pLogPalette );
}

RGBQUAD *CImageObject::GeneratePopularityPalette( int nColors, unsigned char *pBits, int nBits, int nWidth, int nHeight )
{
	RGBQUAD *pRGBQuad = new RGBQUAD[ nColors ];
	if( pRGBQuad == NULL )
		return( GenerateFixedPalette( nColors ) );
	memset( pRGBQuad, 0, nColors * sizeof( RGBQUAD ) );
	BYTE bzColorMap[ 256 ][ 3 ];
	if( !::Popularity( pBits, nBits, nWidth, nHeight, bzColorMap ) )
	{
		delete[] pRGBQuad;
		return( GenerateFixedPalette( nColors ) );
	}
	for( int i=0; i<nColors; i++ )
	{
		pRGBQuad[ i ].rgbRed = bzColorMap[ i ][ 0 ];
		pRGBQuad[ i ].rgbGreen = bzColorMap[ i ][ 1 ];
		pRGBQuad[ i ].rgbBlue = bzColorMap[ i ][ 2 ];
	}
	return( pRGBQuad );
}

RGBQUAD *CImageObject::GenerateMedianCutPalette( int nColors, unsigned char *pBits, int nBits, int nWidth, int nHeight )
{
	RGBQUAD *pRGBQuad = new RGBQUAD[ nColors ];
	if( pRGBQuad == NULL )
		return( GenerateFixedPalette( nColors ) );
	memset( pRGBQuad, 0, nColors * sizeof( RGBQUAD ) );
	BYTE bzColorMap[ 256 ][ 3 ];
	WORD *Hist = new WORD[ 32768 ];
	if( Hist == NULL )
	{
		delete [] pRGBQuad;
		return( GenerateFixedPalette( nColors ) );
	}
	memset( Hist, 0, 32768 * sizeof( WORD ) );
	int nWidthBytes = GetWidthInBytes( nBits, nWidth );

	for( int y=0; y<nHeight; y++ )
	{
		unsigned char *pData = pBits;
		unsigned char ucRed, ucGreen, ucBlue;
		WORD wColor;
		pData += ( y * nWidthBytes );
		for( int x=0; x<nWidth; x++ )
		{
			switch( nBits )
			{
				case 16:
					GET_RGB_16( ucRed, ucGreen, ucBlue, &pData[ 2*x ] );
					break;
				case 24:
					ucRed = pData[ 3*x + 2 ];
					ucGreen = pData[3*x + 1 ];
					ucBlue = pData[ 3*x ];
					break;
				case 32:
					GET_RGB_32( ucRed, ucGreen, ucBlue, &pData[ 4*x ] );
					break;
			}
			wColor = _RGB( ucRed, ucGreen, ucBlue );
			if( Hist[ wColor ] < 65535 )
				Hist[ wColor ]++;
		}
	}
	
	::MedianCut( Hist, bzColorMap, ( int )256 );
	for( int i=0; i<nColors; i++ )
	{
		pRGBQuad[ i ].rgbRed = bzColorMap[ i ][ 0 ];
		pRGBQuad[ i ].rgbGreen = bzColorMap[ i ][ 1 ];
		pRGBQuad[ i ].rgbBlue = bzColorMap[ i ][ 2 ];
	}
	delete[] Hist;
	return( pRGBQuad );
}

RGBQUAD *CImageObject::GenerateFixedPalette( int nColors )
{
	RGBQUAD *pRGBQuad = new RGBQUAD[ nColors ];
	if( pRGBQuad == NULL )
		return( NULL );
	static int nzColors[] = {	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 = ( ( nColors + 15 ) / 16 );
	for( int i=0; i<nSteps; i++ )
	{
		for( int j=0; j<16; j++ )
		{
			if( i * 16 + j < nColors )
			{
				int r, g, b;
				r = nzColors[ 3*j ];
				g = nzColors[ 3*j + 1 ];
				b = nzColors[ 3*j + 2 ];
				r = ( ( nSteps - i ) * r ) / nSteps;
				g = ( ( nSteps - i ) * g ) / nSteps;
				b = ( ( nSteps - i ) * b ) / nSteps;
				pRGBQuad[ 16*i + j ].rgbRed = ( unsigned char )r;
				pRGBQuad[ 16*i + j ].rgbGreen = ( unsigned char )g;
				pRGBQuad[ 16*i + j ].rgbBlue = ( unsigned char )b;
			}
		}
	}
	return( pRGBQuad );
}

// Diagnostics and dump member functions, overrided
#ifdef _DEBUG
void CImageObject::Dump( CDumpContext& dc ) const
{
  // call base class function first
  CObject::Dump( dc );
  // now do the stuff for our specific class
//  dc << "last name: " << m_lastName << "\n" << "first name: " << m_firstName << "\n";
}

void CImageObject::AssertValid() const
{ 
	// call inherited AssertValid first
  CObject::AssertValid();
	// check CImageObject members...
//  ASSERT( !m_strName.IsEmpty()); // Must have a name
//  ASSERT( m_salary > 0 ); // Must have an income
} 

#endif

/***********************************************************************
*  Description: this function was added by maple,2004.3.18
*
*  函数名称:LoadDIBTOBuf
* 
*  参数:  BYTE * buf   --  传入的用于放置象素值的区域的指针 
*   
*  返回值:  bool
*
*  说明:    该函数将图象DIB中对应的象素值转移到m_buf中,变成同一格式,
*            便于处理。        
************************************************************************/

bool CImageObject::LoadDIBToBuf(BYTE * buf)
{
	if(m_hDib == NULL)
		return FALSE;

  	RGBQUAD color ;
	COLORREF colorref;

	if(m_pDib)
		m_pDib = (BYTE *)::GlobalUnlock(m_hDib);
	m_pDib = (BYTE *)::GlobalLock(m_hDib);

	if(m_pDib!=NULL)
	{
		for( int j=0; j<m_nHeight; j++)
			for(int i=0; i<m_nWidth; i++) 
			{
				color = GetPixelColor( i, j );
				colorref =RGB(color.rgbRed, color.rgbGreen, color.rgbBlue);
				unsigned long temp=(long)j*(long)m_nWidth*3+(long)i*3;
			  	    *(buf+temp)=GetBValue(colorref);
			        *(buf+temp+1)=GetGValue(colorref);
				    *(buf+temp+2)=GetRValue(colorref);
			}
	}

	::GlobalUnlock(m_hDib);
 
	return TRUE;	
}

/***********************************************************************
*  Description: this function was added by maple,2004.3.18
*
*  函数名称:UpdateDIB
* 
*  参数:  int nNewWidth    -- 图象经过处理后新的宽度   
*            int nNewHeight   -- 图象经过处理后新的高度
* 
*  返回值:  bool
*
*  说明:    该函数用处理后的buf中的象素值来更新DIB,
*            并根据传入的新的高度和宽度来决定是否新建一DIB。            
************************************************************************/

bool CImageObject::UpdateDIB(int nNewWidth,int nNewHeight,BYTE * buf)
{
    // if the size of the image has no change,
	// we only need to update the old DIB.

	if(nNewWidth == m_nWidth && nNewHeight == m_nHeight)
	{
    	RGBQUAD color ;

 	    if(m_pDib!=NULL)
		    ::GlobalUnlock(m_hDib);
	    m_pDib = (BYTE *)::GlobalLock(m_hDib);

	    if(m_pDib!=NULL)
		{
    	    for( int j=0; j<m_nHeight; j++)
		        for( int i=0; i<m_nWidth; i++)
				{   
			       unsigned long temp=(long)j*(long)m_nWidth*3+(long)i*3;
              	   BYTE r,g,b;
             	   b=*(buf+temp);
               	   g=*(buf+temp+1);
               	   r=*(buf+temp+2);

			       color.rgbRed   = r ;
			       color.rgbGreen = g;
			       color.rgbBlue  = b;
		    	   SetPixelColor( i, j, color ) ;
				} 
		    ::GlobalUnlock(m_hDib);
			return(true);
		}
		else
		{
		    ::GlobalUnlock(m_hDib);
			return(false);
		}


	}
	// the size of the image has been changed
	// we must create a new DIb to replace the old one.
	else   
	{
		RGBQUAD color ;
		HGLOBAL hNewDib;
		DWORD dwNewSize;
		BYTE * pNewBuf;
		BYTE * pNewBits;
		BITMAPFILEHEADER *pOldBFH,*pNewBFH;
		BITMAPINFOHEADER *pOldBIH,*pNewBIH;
		RGBQUAD *pOldPalette,*pNewPalette;

	    if(m_pDib!=NULL)
		    ::GlobalUnlock(m_hDib);
	    m_pDib = (BYTE *)::GlobalLock(m_hDib);
		if(m_pDib==NULL)
		{
			::GlobalUnlock(m_hDib);
			return(false);
		}

		dwNewSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
			     +m_nColors*sizeof(RGBQUAD)+GetWidthInBytes(m_nBits,nNewWidth)*nNewHeight;
		hNewDib = :: GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,dwNewSize);
		if(hNewDib==NULL)
		{
			::GlobalUnlock(m_hDib);
			return (false);
		}

		pNewBuf = (BYTE *)::GlobalLock(hNewDib);
		if(pNewBuf==NULL)
		{
            ::GlobalFree(hNewDib);
			::GlobalUnlock(m_hDib);
			return (false);
		}
   
		pOldBFH = (BITMAPFILEHEADER *)m_pDib;
		pOldBIH = (BITMAPINFOHEADER *)(m_pDib+sizeof(BITMAPFILEHEADER));
		pOldPalette = (RGBQUAD *)(m_pDib+sizeof(BITMAPFILEHEADER)+
			                   sizeof(BITMAPINFOHEADER));
		
		pNewBFH = (BITMAPFILEHEADER *) pNewBuf;
		pNewBIH = (BITMAPINFOHEADER *) (pNewBuf+sizeof(BITMAPFILEHEADER));
		pNewPalette = (RGBQUAD *)(pNewBuf+sizeof(BITMAPFILEHEADER)+
			                   sizeof(BITMAPINFOHEADER));
		pNewBits = pNewBuf+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
			       +m_nColors*sizeof(RGBQUAD);

		*pNewBFH = *pOldBFH;
		*pNewBIH = *pOldBIH; 
        pNewBFH->bfSize = dwNewSize;
		pNewBIH->biWidth = (LONG)nNewWidth;
		pNewBIH->biHeight = (LONG)nNewHeight;
		pNewBIH->biSizeImage = (DWORD)GetWidthInBytes(m_nBits,nNewWidth)*nNewHeight;
  
		for(int k=0;k<m_nColors;k++)
            pNewPalette[k] = pOldPalette[k];
 
		// very important!!
        // if we miss the following two lines,the display of the image
  		m_nWidth = nNewWidth;         
		m_nHeight = nNewHeight; 
		
        m_nPlanes = pNewBIH->biPlanes;      
		m_nBits = pNewBIH->biBitCount;
		m_nColors = pNewBIH->biClrUsed;
		m_nPaletteInBytes = m_nColors*sizeof(RGBQUAD);
		
		
		// will be wrong!
		::GlobalUnlock(m_hDib);
		::GlobalFree(m_hDib);
		::GlobalUnlock(hNewDib);
		SetDib(hNewDib);
       		
	    if(m_pDib)
		    m_pDib = (BYTE *)::GlobalUnlock(m_hDib);
	    m_pDib = (BYTE *)::GlobalLock(m_hDib);

	    if(m_pDib!=NULL)
		{
    	    for( int j=0; j<m_nHeight; j++)
		        for( int i=0; i<m_nWidth; i++)
				{   
			       unsigned long temp=(long)j*(long)m_nWidth*3+(long)i*3;
              	   BYTE r,g,b;
             	   b=*(buf+temp);
               	   g=*(buf+temp+1);
               	   r=*(buf+temp+2);

			       color.rgbRed   = r ;
			       color.rgbGreen = g;
			       color.rgbBlue  = b;
		    	   SetPixelColor( i, j, color ) ;
				} 

	        ::GlobalUnlock(m_hDib);
     	    return TRUE;
		}
		else
		{
			::GlobalUnlock(m_hDib);
			return(false);
		}
	}

}



/***********************************************************************
*  Description: this function was added by maple,2004.3.22
*
*  函数名称:CreatDIBFromBits
* 
*  参数:  int nWidth    -- 要新建的图象的宽度   
*            int nHeight   -- 要新建的图象的高度
*            BYTE * buf    -- 存放象素值的内存区域指针
* 
*  返回值:  bool
*
*  说明:    该函数利用一块存放象素值的内存区域来创建一个DIB,所
*            创建的图象是24位位图。            
************************************************************************/


bool CImageObject::CreateDIBFromBits(int nWidth,int nHeight,BYTE * buf)
{
    RGBQUAD color;
	HGLOBAL hDib;
	DWORD dwSize;
	BYTE * pBuf;
	BITMAPFILEHEADER *pBFH;
	BITMAPINFOHEADER *pBIH;

	dwSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
			 +GetWidthInBytes(24,nWidth)*nHeight;
	hDib = :: GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,dwSize);
	if(hDib==NULL)
	{
		return (false);
	}
	
	pBuf = (BYTE *)::GlobalLock(hDib);
	if(pBuf==NULL)
	{
		::GlobalFree(hDib);
		return (false);
	}
	pBFH = (BITMAPFILEHEADER *) pBuf;
	pBIH = (BITMAPINFOHEADER *) (pBuf+sizeof(BITMAPFILEHEADER));
    
	pBFH->bfType = (WORD)19778;
	pBFH->bfSize = (DWORD)dwSize;
	pBFH->bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
	
	pBIH->biSize = (DWORD)40;
	m_nWidth = pBIH->biWidth = (LONG)nWidth;
	m_nHeight = pBIH->biHeight = (LONG)nHeight;
	m_nPlanes = pBIH->biPlanes = (WORD)1;
	m_nBits = pBIH->biBitCount = (WORD)24;
	pBIH->biCompression = BI_RGB;
	pBIH->biSizeImage = (DWORD)GetWidthInBytes(24,nWidth)*nHeight;
//	pBIH->biXPelsPerMeter = (LONG)4724;
//	pBIH->biYPelsPerMeter = (LONG)4724; 
    m_nColors = pBIH->biClrUsed = (DWORD)0;
	pBIH->biClrImportant = (DWORD)0;

	m_nPaletteInBytes = 0;     // used in Draw() 

	::GlobalUnlock(hDib);
	SetDib(hDib);
	
	if(m_pDib)
		m_pDib = (BYTE *)::GlobalUnlock(m_hDib);
	m_pDib = (BYTE *)::GlobalLock(m_hDib);
	
	if(m_pDib!=NULL)     
	{
		BYTE * pBits = m_pDib+sizeof(BITMAPFILEHEADER)
			+sizeof(BITMAPINFOHEADER);

		for( int k=0; k<GetWidthInBytes(24,nWidth)*nHeight; k++)
			pBits[k] = 0;

		for( int j=0; j<m_nHeight; j++)
			for( int i=0; i<m_nWidth; i++)
			{   
 				unsigned long temp=(long)j*(long)m_nWidth*3+(long)i*3;				
				BYTE r,g,b;
				b=*(buf+temp);
				g=*(buf+temp+1);
				r=*(buf+temp+2);
				
				color.rgbRed   = r ;
				color.rgbGreen = g;
				color.rgbBlue  = b;
				SetPixelColor( i, j, color ) ;
			} 
			
			::GlobalUnlock(m_hDib);
			return TRUE;
	}
	else
	{
		::GlobalUnlock(m_hDib);
		return(false);
	}
}


/***********************************************************************
*  Description: this function was added by maple,2004.3.22
*
*  函数名称:CreatFromHANDLE
* 
*  参数:  HANDLE handle    -- 要新建的图象的宽度   
*
*  返回值:  bool
*
*  说明:    该函数利用从剪贴板获得的标准DIB句柄创建一个用于
*            该ImageObject的包含BITMAPFILEHEADER的DIB。            
************************************************************************/

bool CImageObject::CreateFromHANDLE(HANDLE handle)
{

	HANDLE hDib;
	BYTE * pBuf,*pTemp;
	BITMAPFILEHEADER *pBFH;
	BITMAPINFOHEADER *pBIH;
	DWORD size = ::GlobalSize(handle);
	DWORD dwSize = ::GlobalSize(handle)+sizeof(BITMAPFILEHEADER);
	hDib = :: GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,dwSize);
	if(hDib==NULL)
	{
		return (false);
	}
	pBuf = (BYTE *)::GlobalLock(hDib);
	if(pBuf==NULL)
	{
		::GlobalFree(hDib);
		return(false);
	}
	pTemp = (BYTE *)::GlobalLock(handle);
	if(pTemp==NULL)
	{
		return (false);
	}

    pBFH = (BITMAPFILEHEADER *)pBuf;
	pBFH->bfType = (WORD)19778;
	pBFH->bfSize = (DWORD)dwSize;
	pBFH->bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);


	memcpy(pBuf+sizeof(BITMAPFILEHEADER),pTemp,size);

	pBIH = (BITMAPINFOHEADER *)(pBuf+sizeof(BITMAPFILEHEADER));
	m_nWidth = pBIH->biWidth;
	m_nHeight = pBIH->biHeight;
	m_nPlanes = pBIH->biPlanes;
	m_nBits = pBIH->biBitCount;
	m_nColors = pBIH->biClrUsed;
	m_nPaletteInBytes = m_nColors*sizeof(RGBQUAD);
    

⌨️ 快捷键说明

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