📄 imageobject.cpp
字号:
pTemp = (char *) ::GlobalLock( m_hDib );
m_nLastError = IMAGELIB_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 = IMAGELIB_LOGICAL_PALETTE_CREATION_ERROR;
goto ProcessPaletteExit;
}
m_Palette.CreatePalette( pPalette );
delete [] pPalette;
}
m_nLastError = IMAGELIB_SUCCESS;
ProcessPaletteExit:
::GlobalUnlock( m_hDib );
}
//清除图像
void CImageObject::KillImage( void )
{
if( m_hDib ) ::GlobalFree( m_hDib );
m_hDib = NULL;
if( m_pLogPal != NULL ) delete [] m_pLogPal;
m_pLogPal = NULL;
if( m_pszFilename != NULL ) delete [] m_pszFilename;
m_pszFilename = NULL;
m_Palette.DeleteObject();
}
////////////////////////////////////////////////////////////////////////
//BOOL SetPalette( CDC *pDC )
//----------------------------------------------------------------------
//基本功能:本函数将该设备描述表的调色板分配给相应的图像。当一个图像被载
// 入时,它的调色板信息便被存入CImageObject对象中。
//----------------------------------------------------------------------
//参数说明:CDC *pDC
//----------------------------------------------------------------------
//返 回 值:BOOL:成功返回TRUE,失败返回FALSE
//----------------------------------------------------------------------
//编 者:耿 楠
//最后编改:2001年11月20日
////////////////////////////////////////////////////////////////////////
BOOL CImageObject::SetPalette( CDC *pDC )
{
m_nLastError = IMAGELIB_HDIB_NULL;
if( m_hDib == NULL ) return( FALSE );
pDC->SelectPalette( &m_Palette, FALSE );
pDC->RealizePalette();
m_nLastError = IMAGELIB_SUCCESS;
return( TRUE );
}
////////////////////////////////////////////////////////////////////////
//BOOL IsLoaded( void )
//----------------------------------------------------------------------
//基本功能:本函数判断是否已经载入了一幅图像
//----------------------------------------------------------------------
//参数说明:无
//----------------------------------------------------------------------
//返 回 值:BOOL:成功返回TRUE,失败返回FALSE
//----------------------------------------------------------------------
//编 者:耿 楠
//最后编改:2001年11月20日
////////////////////////////////////////////////////////////////////////
BOOL CImageObject::IsLoaded( void )
{
return( m_hDib != NULL );
}
//得到指针
void *CImageObject::GetDIBPointer( int *nWidthBytes,
int nNewBits,
int *nNewWidthBytes,
int nNewWidth )
{
m_nLastError = IMAGELIB_HDIB_NULL;
if( m_hDib == NULL ) return( NULL );
void *pTemp;
pTemp = ::GlobalLock( m_hDib );
m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
if( pTemp == NULL ) return( NULL );
if( nWidthBytes != NULL ) *nWidthBytes = WidthBytes( m_nBits, m_nWidth );
if( nNewWidthBytes != NULL ){
if( nNewWidth == -1 ) nNewWidth = m_nWidth;
*nNewWidthBytes = WidthBytes( nNewBits, nNewWidth );
}
return( pTemp );
}
//字节宽度
int CImageObject::WidthBytes( 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 );
}
//坐标调整
void CImageObject::NormalizeCoordinates( int *nX1, int *nY1, int *nX2, int *nY2, BOOL *bCompleteImage, BOOL *bLessThanHalf )
{
if( *nX1 == -1 ) *nX1 = 0;
if( *nY1 == -1 ) *nY1 = 0;
if( *nX2 == -1 ) *nX2 = m_nWidth - 1;
if( *nY2 == -1 ) *nY2 = m_nHeight - 1;
if( *nX1 > *nX2 ){
int nTemp;
nTemp = *nX1;
*nX1 = *nX2;
*nX2 = nTemp;
}
if( *nY1 > *nY2 ){
int nTemp;
nTemp = *nY1;
*nY1 = *nY2;
*nY2 = nTemp;
}
if( *nX1 < 0 ) *nX1 = 0;
if( *nX2 > m_nWidth - 1 ) *nX2 = m_nWidth - 1;
if( *nX2 < 0 ) *nX2 = 0;
if( *nX2 > m_nWidth - 1 ) *nX2 = m_nWidth - 1;
if( *nY1 < 0 ) *nY1 = 0;
if( *nY1 > m_nHeight - 1 ) *nY1 = m_nHeight - 1;
if( *nY2 < 0 ) *nY2 = 0;
if( *nY2 > m_nHeight - 1 ) *nY2 = m_nHeight - 1;
if( bCompleteImage != NULL ) *bCompleteImage = TRUE;
if( bLessThanHalf != NULL ) *bLessThanHalf = FALSE;
if( *nX1 > 0 || *nY1 > 0 || *nX2 < m_nWidth - 1 || *nY2 < m_nHeight - 1 ){
if( bCompleteImage != NULL ) *bCompleteImage = FALSE;
DWORD dwTotalPixels, dwThesePixels;
dwTotalPixels = (DWORD) m_nWidth * m_nHeight;
dwThesePixels = (DWORD) ( (*nX2) - (*nX1) + 1 ) * (DWORD) ( (*nY2) - (*nY1) + 1 );
if( bLessThanHalf != NULL && dwThesePixels <= dwTotalPixels / 2 ) *bLessThanHalf = TRUE;
}
}
//复制
void CImageObject::operator= (const CImageObject &ImageObject)
{
KillImage();
m_nWidth = ImageObject.m_nWidth;
m_nHeight = ImageObject.m_nHeight;
m_nPlanes = ImageObject.m_nPlanes;
m_nBits = ImageObject.m_nBits;
m_nColors = ImageObject.m_nColors;
m_nImageType = ImageObject.m_nImageType;
m_nX = ImageObject.m_nX;
m_nY = ImageObject.m_nY;
m_nLastError = ImageObject.m_nLastError;
m_nScreenPlanes = ImageObject.m_nScreenPlanes;
m_nScreenBits = ImageObject.m_nScreenBits;
m_nPaletteBytes = ImageObject.m_nPaletteBytes;
m_nQuality = ImageObject.m_nQuality;
m_nPaletteCreationType = ImageObject.m_nPaletteCreationType;
int nNumColors = m_nColors;
int nWidthBytes = WidthBytes( m_nBits, m_nWidth );
if( ImageObject.m_hDib != NULL ){
DWORD dwSize = ::GlobalSize( ImageObject.m_hDib );
char *pData = (char *) ::GlobalLock( ImageObject.m_hDib );
if( pData != NULL ){
HGLOBAL hGlobal = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwSize );
if( hGlobal != NULL ){
char *pDestData = (char *) ::GlobalLock( hGlobal );
if( pDestData != NULL ){
memcpy( pDestData, pData, dwSize );
if( nNumColors != 0 ) CreatePaletteFromDIB( (RGBQUAD *) &pData[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)], nNumColors );
else if( ImageObject.m_pLogPal != NULL ){
m_pLogPal = (LOGPALETTE *) new char [sizeof(LOGPALETTE)+ImageObject.m_pLogPal->palNumEntries*sizeof(PALETTEENTRY)];
if( m_pLogPal != NULL ){
for( int i=0; i<ImageObject.m_pLogPal->palNumEntries; i++ ) m_pLogPal[i] = ImageObject.m_pLogPal[i];
m_Palette.CreatePalette( m_pLogPal );
}
}
::GlobalUnlock( hGlobal );
m_hDib = hGlobal;
}
else ::GlobalFree( hGlobal );
}
::GlobalUnlock( ImageObject.m_hDib );
}
}
if( ImageObject.m_pszFilename != NULL ){
m_pszFilename = new char [strlen(ImageObject.m_pszFilename)+1];
strcpy( m_pszFilename, ImageObject.m_pszFilename );
}
}
//从位图创建调色板
void CImageObject::CreatePaletteFromDIB( RGBQUAD *pRGBPalette, int nNumColors )
{
if( pRGBPalette != NULL ){
LOGPALETTE *pPalette;
pPalette = CreateLogPalette( pRGBPalette, nNumColors );
if( pPalette != NULL ){
m_Palette.CreatePalette( pPalette );
delete [] pPalette;
}
else m_nLastError = IMAGELIB_LOGICAL_PALETTE_CREATION_ERROR;
}
}
//得到最近索引
int CImageObject::GetNearestIndex( unsigned char ucRed,
unsigned char ucGreen,
unsigned char ucBlue,
RGBQUAD *pRGBPalette,
int nNumColors )
{
int i, Index = 0;
DWORD NewDiff, Diff = 100000L;
DWORD Red, Green, Blue;
for( i=0; i<nNumColors; i++ ){
if( ucRed > pRGBPalette[i].rgbRed ) Red = (DWORD) ( pRGBPalette[i].rgbRed - ucRed );
else Red = (DWORD) ( ucRed - pRGBPalette[i].rgbRed );
if( ucGreen > pRGBPalette[i].rgbGreen ) Green = (DWORD) ( pRGBPalette[i].rgbGreen - ucGreen );
else Green = (DWORD) ( ucGreen - pRGBPalette[i].rgbGreen );
if( ucBlue > pRGBPalette[i].rgbBlue ) Blue = (DWORD) ( pRGBPalette[i].rgbBlue - ucBlue );
else Blue = (DWORD) ( ucBlue - pRGBPalette[i].rgbBlue );
NewDiff = ( Red * Red ) + ( Green * Green ) + ( Blue * Blue );
if( NewDiff < Diff ){
if( NewDiff <= 1 ) return( i );
Diff = NewDiff;
Index = i;
}
}
return( Index );
}
////////////////////////////////////////////////////////////////////////
//BOOL ChangeFormat( int nNewBitsPerPixel )
//----------------------------------------------------------------------
//基本功能:本函数将图像从当前分辨率转化为指定分辨率。
//----------------------------------------------------------------------
//参数说明:int nNewBitsPerPixel
//----------------------------------------------------------------------
//返 回 值:BOOL:成功返回TRUE,失败返回FALSE
//----------------------------------------------------------------------
//编 者:耿 楠
//最后编改:2001年11月20日
////////////////////////////////////////////////////////////////////////
BOOL CImageObject::ChangeFormat( int nNewBitsPerPixel )
{
m_nLastError = IMAGELIB_SUCCESS;
if( nNewBitsPerPixel == m_nBits ) return( TRUE );
int nOldWidthBytes, nNewWidthBytes;
char *pBuffer = (char *) GetDIBPointer( &nOldWidthBytes, nNewBitsPerPixel, &nNewWidthBytes );
if( pBuffer == NULL ) return( FALSE );
BITMAPINFOHEADER *pOldBIH, *pNewBIH;
BITMAPFILEHEADER *pOldBFH, *pNewBFH;
RGBQUAD *pOldRGBPalette, *pNewRGBPalette;
unsigned char *pOldBits, *pNewBits;
int nNumColors, nNumNewColors;
pOldBFH = (BITMAPFILEHEADER *) pBuffer;
pOldBIH = (BITMAPINFOHEADER *) &pBuffer[sizeof(BITMAPFILEHEADER)];
pOldRGBPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
nNumColors = m_nColors;
nNumNewColors = 1 << nNewBitsPerPixel;
if( nNewBitsPerPixel > 8 ) nNumNewColors = 0;
pOldBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
if( m_nBits >= 16 && nNewBitsPerPixel < 16 ){
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -