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

📄 imageobject.cpp

📁 分水岭算法
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		pSrc += ( nOldWidthInBytes * y );
		pDest = pNewBits;
		pDest += ( nNewWidthInBytes * 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:
					GET_RGB_16( ucRed, ucGreen, ucBlue, &pSrc[ 2*x ] );
					break;
				case 24:
					ucRed = pSrc[ 3*x + 2 ];
					ucGreen = pSrc[ 3*x + 1 ];
					ucBlue = pSrc[ 3*x ];
					break;
				case 32:
					GET_RGB_32( ucRed, ucGreen, ucBlue, &pSrc[ 4*x ] );
					break;
			}
			switch( nColorDepth )
			{
				case 1:
					if( !( x & 7 ) )
						pDest[ x/8 ] = 0;
					pDest[ x/8 ] |= ( unsigned char )GetNearestIndex( ucRed, ucGreen, ucBlue, pNewRGBPalette, nNewColors ) << ( x & 7 );
					break;
				case 4:
					if( !( x & 1 ) )
						pDest[ x/2 ] = ( unsigned char )GetNearestIndex( ucRed, ucGreen, ucBlue, pNewRGBPalette, nNewColors ) << 4;
					else
						pDest[ x/2 ] |= ( unsigned char )GetNearestIndex( ucRed, ucGreen, ucBlue, pNewRGBPalette, nNewColors );
					break;
				case 8:
					pDest[ x ] = ( unsigned char )GetNearestIndex( ucRed, ucGreen, ucBlue, pNewRGBPalette, nNewColors );
					break;
				case 16:
					PUT_RGB_16( ucRed, ucGreen, ucBlue, &pDest[ 2*x ] );
					break;
				case 24:
					pDest[ 3*x + 2 ] = ucRed;
					pDest[ 3*x + 1 ] = ucGreen;
					pDest[ 3*x ] = ucBlue;
					break;
				case 32:
					PUT_RGB_32( ucRed, ucGreen, ucBlue, &pDest[ 4*x ] );
					break;
			}
		}
	}

	::GlobalUnlock( m_hDib );
	::GlobalFree( m_hDib );
	::GlobalUnlock( hGlobal );
	m_hDib = hGlobal;
	LoadImageHeader();
	return( true );
}

//////////////////////////////////////////
// Palette functions
//
bool CImageObject::SetPalette( CDC *pDC )
{
	m_nLastError = GL_HDIB_NULL;
	if( m_hDib == NULL )
		return( false );
	pDC->SelectPalette( &m_Palette, false );
	pDC->RealizePalette();
	m_nLastError = GL_SUCCESS;
	return( true );
}

bool CImageObject::GetPaletteData( RGBQUAD *pRGBPalette )
{
	m_nLastError = GL_HDIB_NULL;
	if( m_hDib == NULL )
		return( false );
	char *pTemp;
	pTemp = ( char * )::GlobalLock( m_hDib );
	m_nLastError = GL_MEMORY_LOCK_ERROR;
	if( pTemp == NULL )
		return( false );
	memcpy( pRGBPalette, &pTemp[ sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) ], m_nPaletteInBytes );
	m_nLastError = GL_SUCCESS;
	::GlobalUnlock( m_hDib );
	return( true );
}

RGBQUAD *CImageObject::GetPaletteData( void )
{
	m_nLastError = GL_HDIB_NULL;
	if( m_hDib == NULL )
		return( NULL );
	m_nLastError = GL_NO_PALETTE_FOR_HIGH_COLOR;
	if( m_nColors <= 0 || m_nColors > 256 )
		return( NULL );
	RGBQUAD *pRGBPalette;
	pRGBPalette = new RGBQUAD[ m_nColors ];
	if( pRGBPalette == NULL )
	{
		m_nLastError = GL_MEMORY_ALLOCATION_ERROR;
		return( NULL );
	}
	char *pTemp;
	pTemp = ( char * )::GlobalLock( m_hDib );
	m_nLastError = GL_MEMORY_LOCK_ERROR;
	if( pTemp == NULL )
	{
		delete[] pRGBPalette;
		return( NULL );
	}
	memcpy( pRGBPalette, &pTemp[ sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) ], m_nColors * sizeof( RGBQUAD ) );
	m_nLastError = GL_SUCCESS;
	::GlobalUnlock( m_hDib );
	return( pRGBPalette );
}

//////////////////////////////////////////
// Load and Save functions
//
bool CImageObject::LoadFromFile( const char *pszFileName, CDC *pDC, int nX, int nY )
{
	m_nImageType = ::FileType( pszFileName );
	if( m_nImageType == 0 )
	{
		m_nLastError = GL_UNSUPPORTED_FILETYPE;
		return( false );
	}
	DestroyImage();
	m_pszFileName = new char[ strlen( pszFileName ) + 1 ];
	if( m_pszFileName != NULL )
		strcpy( m_pszFileName, pszFileName );
	switch( m_nImageType )
	{
		case GT_BMP:
			m_hDib = ::LoadBMP( pszFileName );
			if( m_hDib == NULL )
			{
				m_nLastError = ::GetLastPicLibError();
				return( false );
			}
			break;
		case GT_GIF:
			m_hDib = ::LoadGIF( pszFileName );
			if( m_hDib == NULL )
			{
				m_nLastError = ::GetLastPicLibError();
				return( false );
			}
			break;
		case GT_JPG:
			m_hDib = ::LoadJPG( pszFileName );
			if( m_hDib == NULL )
			{
				m_nLastError = ::GetLastPicLibError();
				return( false );
			}
			break;
		case GT_PCX:
			m_hDib = ::LoadPCX( pszFileName );
			if( m_hDib == NULL )
			{
				m_nLastError = ::GetLastPicLibError();
				return( false );
			}
			break;
		case GT_TGA:
			m_hDib = ::LoadTGA( pszFileName );
			if( m_hDib == NULL )
			{
				m_nLastError = ::GetLastPicLibError();
				return( false );
			}
			break;
		case GT_TIF:
			m_hDib = ::LoadTIF( pszFileName );
			if( m_hDib == NULL )
			{
				m_nLastError = ::GetLastPicLibError();
				return( false );
			}
			break;
		}
	LoadImageHeader();
	LoadPalette();
	
    //----------------------------------------------------------------------
	// added by maple to support GetPixelColor() and SetPixelColor()  
	// 2004.3.26
	if(m_pDib!=NULL)
		::GlobalUnlock(m_hDib);
	m_pDib = (BYTE *)::GlobalLock(m_hDib);

	//----------------------------------------------------------------------
	if( pDC != NULL )
		Draw( pDC, nX, nY );
	return( true );
}

bool CImageObject::SaveToFile( const char *pszFileName, int nType )
{
	if( nType == -1 )
		nType = GetExtensionIndex( pszFileName );
	if( nType < GT_FIRSTTYPE || nType > GT_LASTTYPE )
		return( false );
	m_nImageType = nType;
	delete[] m_pszFileName;
	m_pszFileName = new char [ strlen( pszFileName ) + 1 ];
	if( m_pszFileName != NULL )
		strcpy( m_pszFileName, pszFileName );
	switch( m_nImageType )
	{
		case GT_BMP:
			if( SaveBMP( pszFileName, m_hDib ) )
				return( true );
		  break;
		case GT_GIF:
			if( ::SaveGIF( pszFileName, m_hDib ) )
				return( true );
		  break;
		case GT_JPG:
			if( ::SaveJPG( pszFileName, m_hDib, m_nQuality ) )
				return( true );
		  break;
		case GT_PCX:
			if( ::SavePCX( pszFileName, m_hDib ) )
				return( true );
		  break;
		case GT_TGA:
			if( ::SaveTGA( pszFileName, m_hDib ) )
				return( true );
		  break;
		case GT_TIF:
			if( ::SaveTIF( pszFileName, m_hDib ) )
				return( true );
		  break;
	}
	return( false );  // true?
}

//////////////////////////////////////////
// Draw functions
//
bool CImageObject::Draw( CDC *pDC, int nX, int nY )
{
	if( nX != -1 )
		m_nX = nX;
	if( nY != -1 )
		m_nY = nY;
	m_nLastError = GL_HDIB_NULL;
	if( m_hDib == NULL )
		return( false );
	char *pTemp;
	pTemp = ( char * )::GlobalLock( m_hDib );
	m_nLastError = GL_MEMORY_LOCK_ERROR;
	if( pTemp == NULL )
		return( NULL );
	BITMAPINFOHEADER *pBIH;
	pBIH = ( BITMAPINFOHEADER * )&pTemp[ sizeof( BITMAPFILEHEADER ) ];
	::SetStretchBltMode(pDC->GetSafeHdc(),COLORONCOLOR);
	int nRet = ::StretchDIBits( pDC->m_hDC, m_nX, m_nY, m_nWidth, m_nHeight,
		                        0, 0, m_nWidth, m_nHeight,
		                        (const void FAR *) &pTemp[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+m_nPaletteInBytes], 
		                        (BITMAPINFO *) pBIH,
								DIB_RGB_COLORS, 
								SRCCOPY );
	::GlobalUnlock( m_hDib );
	m_nLastError = GL_STRETCHDIBITS_ERROR;
	if( nRet != m_nHeight )
		return( false );
	m_nLastError = GL_SUCCESS;
	return( true );
}


/***********************************************************************
*  Description: this function was added by maple,2004.3.21
*
*  函数名称:DrawTo
* 
*  参数:  CDC *pDC        -- 绘图设备环境
*            int nDestX      -- 绘制起点横坐标
*            int nDestY      -- 绘制七点纵坐标
*            int nDestWidth  -- 绘制目标区域宽度
*            int nDestHeight -- 绘制目标区域高度
* 
*  返回值:  bool 
*
*  说明:    该函数用于将一图象绘制到指定区域。          
************************************************************************/

bool CImageObject::DrawTo(CDC *pDC,int nDestX ,int nDestY ,int nDestWidth,int nDestHeight)
{
	if( nDestX != -1 )
		m_nX = nDestX;
	if( nDestY != -1 )
		m_nY = nDestY;
	if(nDestWidth != 0)
		m_nDestWidth = nDestWidth;
	if(nDestHeight != 0)
		m_nDestHeight = nDestHeight;
	m_nLastError = GL_HDIB_NULL;
	if( m_hDib == NULL )
		return( false );
	char *pTemp;
	pTemp = ( char * )::GlobalLock( m_hDib );
	m_nLastError = GL_MEMORY_LOCK_ERROR;
	if( pTemp == NULL )
		return( NULL );
	BITMAPINFOHEADER *pBIH;
	pBIH = ( BITMAPINFOHEADER * )&pTemp[ sizeof( BITMAPFILEHEADER ) ];
	::SetStretchBltMode(pDC->GetSafeHdc(),COLORONCOLOR);
	int nRet = ::StretchDIBits( pDC->m_hDC, m_nX, m_nY, m_nDestWidth, m_nDestHeight,
		                        0, 0, m_nWidth, m_nHeight,	
		                        (const void FAR *) &pTemp[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+m_nPaletteInBytes], 
		                        (BITMAPINFO *) pBIH,
								DIB_RGB_COLORS, 
								SRCCOPY );
	::GlobalUnlock( m_hDib );
	m_nLastError = GL_STRETCHDIBITS_ERROR;
	if( nRet != m_nHeight )
		return( false );
	m_nLastError = GL_SUCCESS;
	return( true );
}

bool CImageObject::DrawToHdc(HDC pHdc, int nDestX ,int nDestY ,int nDestWidth,int nDestHeight)
{
	if( nDestX != -1 )
		m_nX = nDestX;
	if( nDestY != -1 )
		m_nY = nDestY;
	if(nDestWidth != 0)
		m_nDestWidth = nDestWidth;
	if(nDestHeight != 0)
		m_nDestHeight = nDestHeight;
	m_nLastError = GL_HDIB_NULL;
	if( m_hDib == NULL )
		return( false );
	char *pTemp;
	pTemp = ( char * )::GlobalLock( m_hDib );
	m_nLastError = GL_MEMORY_LOCK_ERROR;
	if( pTemp == NULL )
		return( NULL );
	BITMAPINFOHEADER *pBIH;
	pBIH = ( BITMAPINFOHEADER * )&pTemp[ sizeof( BITMAPFILEHEADER ) ];
	::SetStretchBltMode(pHdc, COLORONCOLOR);
	int nRet = ::StretchDIBits( pHdc, m_nX, m_nY, m_nDestWidth, m_nDestHeight,
		                        0, 0, m_nWidth, m_nHeight,	
		                        (const void FAR *) &pTemp[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+m_nPaletteInBytes], 
		                        (BITMAPINFO *) pBIH,
								DIB_RGB_COLORS, 
								SRCCOPY );
	::GlobalUnlock( m_hDib );
	m_nLastError = GL_STRETCHDIBITS_ERROR;
	if( nRet != m_nHeight )
		return( false );
	m_nLastError = GL_SUCCESS;
	return( true );
}
//////////////////////////////////////////
// Basic private member functions
//
void CImageObject::LoadImageHeader( void )
{
	m_nLastError = GL_HDIB_NULL;
	if( m_hDib == NULL )
		return;
	char *pTemp;
	BITMAPINFOHEADER *pBIH;
	pTemp = ( char * )::GlobalLock( m_hDib );
	m_nLastError = GL_MEMORY_LOCK_ERROR;
	if( pTemp == NULL )
		return;

	BITMAPFILEHEADER * pBFH;
	pBFH = (BITMAPFILEHEADER *) pTemp;
	WORD bfType = pBFH->bfType;

	pBIH = ( BITMAPINFOHEADER * )&pTemp[ sizeof( BITMAPFILEHEADER ) ];
	m_nWidth = pBIH->biWidth;
	m_nHeight = pBIH->biHeight;
	m_nPlanes = pBIH->biPlanes;
	m_nBits = pBIH->biBitCount;
	m_nColors = 1 << m_nBits;

//	DWORD tmp = pBIH->biClrUsed;
//
//    LONG PIX = pBIH->biXPelsPerMeter;
//	LONG PIY = pBIH->biYPelsPerMeter;


	if( m_nPlanes > 1 )
		m_nColors <<= ( m_nPlanes - 1 );
	if( m_nBits >= 16 )
		m_nColors = 0;
	::GlobalUnlock( m_hDib );
	m_nLastError = GL_SUCCESS;
}

void CImageObject::LoadPalette( void )
{
	m_nLastError = GL_HDIB_NULL;
	if( m_hDib == NULL )
		return;
	CWindowDC WindowDC( NULL );
	m_nScreenPlanes = WindowDC.GetDeviceCaps( PLANES );
	m_nScreenBits = WindowDC.GetDeviceCaps( BITSPIXEL );
	m_nPaletteInBytes = 0;
	m_Palette.DeleteObject();
	if( m_nBits <= 8 )
		m_nPaletteInBytes = m_nColors * sizeof( RGBQUAD );
	if( m_nScreenBits >= 16 )
		return;
	char *pTemp;
	pTemp = ( char * )::GlobalLock( m_hDib );
	m_nLastError = GL_MEMORY_LOCK_ERROR;
	if( pTemp == NULL )
		return;
	if( m_nBits <= 8 )
	{
		RGBQUAD *pRGBPalette;
		pRGBPalette = ( RGBQUAD * )&pTemp[ sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) ];
		LOGPALETTE *pPalette;
		pPalette = CreateLogPalette( pRGBPalette, m_nColors );
		if( pPalette == NULL )
		{
			m_nLastError = GL_LOGICAL_PALETTE_CREATION_ERROR;
			// These statements are inserted by June.
			::GlobalUnlock( m_hDib );
			return;
			//goto LoadPaletteExit;
		}
		m_Palette.CreatePalette( pPalette );
		delete[] pPalette;
	}
	m_nLastError = GL_SUCCESS; 
//LoadPaletteExit:
	::GlobalUnlock( m_hDib );
}

void CImageObject::DestroyImage( void )
{
// add by maple
	if( m_pDib)
		::GlobalUnlock(m_hDib);
	m_pDib = NULL;
//---------------------------------------
	if( m_hDib )
		::GlobalFree( m_hDib );
	m_hDib = NULL;

	if( m_pLogPalette != NULL )
		delete[] m_pLogPalette;
	m_pLogPalette = NULL;
	if( m_pszFileName != NULL )
		delete[] m_pszFileName;
	m_pszFileName = NULL;
	m_Palette.DeleteObject();
}

LOGPALETTE *CImageObject::CreateLogPalette( RGBQUAD *pPalette, int nNumColors )
{
	LOGPALETTE *pLogPalette;
	int i;
	if( pPalette == NULL )
		return( NULL );
	pLogPalette = ( LOGPALETTE * )new char[ sizeof( LOGPALETTE ) + nNumColors * sizeof( PALETTEENTRY ) ];
	if( pLogPalette == NULL )
		return( NULL );
	pLogPalette->palVersion = 0x300;
	pLogPalette->palNumEntries = ( unsigned short )nNumColors;
	for( i=0; i<nNumColors; i++ )
	{
		pLogPalette->palPalEntry[ i ].peRed = pPalette[ i ].rgbRed;
		pLogPalette->palPalEntry[ i ].peGreen = pPalette[ i ].rgbGreen;
		pLogPalette->palPalEntry[ i ].peBlue = pPalette[ i ].rgbBlue;
		pLogPalette->palPalEntry[ i ].peFlags = 0;
	}
	return( pLogPalette );
}

void *CImageObject::GetDIBPointer( int *nWidthBytes, int nNewBits, int *nNewWidthBytes, int nNewWidth )
{
	m_nLastError = GL_HDIB_NULL;
	if( m_hDib == NULL )
		return( NULL );
	void *pTemp;
	pTemp = ::GlobalLock( m_hDib );
	m_nLastError = GL_MEMORY_LOCK_ERROR;
	if( pTemp == NULL )
		return( NULL );
	if( nWidthBytes != NULL )
		*nWidthBytes = GetWidthInBytes( m_nBits, m_nWidth );
	if( nNewWidthBytes != NULL )
	{
		if( nNewWidth == -1 )
			nNewWidth = m_nWidth;
		*nNewWidthBytes = GetWidthInBytes( nNewBits, nNewWidth );
	}
	return( pTemp );
}

int CImageObject::GetWidthInBytes( int nBits, int nWidth )
{
	int nWidthBytes;
	nWidthBytes = nWidth;
	if( nBits == 1 )
		nWidthBytes = ( nWidth + 7 ) / 8;
	else if( nBits == 4 )
		nWidthBytes = ( nWidth + 1 ) / 2;
	else if( nBits == 16 )
		nWidthBytes = nWidth * 2;
	else if( nBits == 24 )
		nWidthBytes = nWidth * 3;
	else if( nBits == 32 )
		nWidthBytes = nWidth * 4;
	while( ( nWidthBytes & 3 ) != 0 )
		nWidthBytes++;
	return( nWidthBytes );
}

int CImageObject::GetNearestIndex( unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue, RGBQUAD *pRGBPalette, int nColors )
{
	int i, Index = 0;
	DWORD NewDiff, Diff = 100000L;
	DWORD dwRed, dwGreen, dwBlue;
	for( i=0; i<nColors; i++ )

⌨️ 快捷键说明

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