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

📄 imageobject.cpp

📁 这是书上的代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		xx = pBIH->biWidth;
		xx = ( xx + 15 ) / 16;
		nWidth = ( pBIH->biWidth + 7 ) / 8;
		}

	for( y=0; y<pBIH->biHeight; y++ ){
		pTemp = pBits;
		pTemp += y * nWidthBytes;
		switch( m_nBits ){
			case 1:
				for( x=0; x<xx; x++ ){
					xt = nWidth - 1 - x;
					Data = pTemp[x];
					Data1 = Data << 7;
					Data1 |= ( ( Data & 0x02 ) << 5 );
					Data1 |= ( ( Data & 0x04 ) << 3 );
					Data1 |= ( ( Data & 0x08 ) << 1 );
					Data1 |= ( ( Data & 0x10 ) >> 1 );
					Data1 |= ( ( Data & 0x20 ) >> 3 );
					Data1 |= ( ( Data & 0x40 ) >> 5 );
					Data1 |= ( ( Data & 0x80 ) >> 7 );

					Tmp = pTemp[xt];
					Tmp1 = Tmp << 7;
					Tmp1 |= ( ( Tmp & 0x02 ) << 5 );
					Tmp1 |= ( ( Tmp & 0x04 ) << 3 );
					Tmp1 |= ( ( Tmp & 0x08 ) << 1 );
					Tmp1 |= ( ( Tmp & 0x10 ) >> 1 );
					Tmp1 |= ( ( Tmp & 0x20 ) >> 3 );
					Tmp1 |= ( ( Tmp & 0x40 ) >> 5 );
					Tmp1 |= ( ( Tmp & 0x80 ) >> 7 );

					pTemp[x] = Tmp1;
					pTemp[xt] = Data1;
					}
				break;
			case 4:
				for( x=0; x<xx; x++ ){
					xt = nWidth - 1 - x;
					Data = pTemp[x];
					Tmp = pTemp[xt];
					Data = ( Data << 4 ) | ( Data >> 4 );
					Tmp = ( Tmp << 4 ) | ( Tmp >> 4 );
					pTemp[x] = Tmp;
					pTemp[xt] = Data;
					}
				break;
			case 8:
				for( x=0; x<xx; x++ ){
					xt = nWidth - 1 - x;
					Data = pTemp[x];
					pTemp[x] = pTemp[xt];
					pTemp[xt] = Data;
					}
				break;
			case 16:
				for( x=0; x<xx; x++ ){
					xt = nWidth - 1 - x;
					Data = pTemp[x*2];
					pTemp[x*2] = pTemp[xt*2];
					pTemp[xt*2] = Data;
					Data = pTemp[x*2+1];
					pTemp[x*2+1] = pTemp[xt*2+1];
					pTemp[xt*2+1] = Data;
					}
				break;
			case 24:
				for( x=0; x<xx; x++ ){
					xt = nWidth - 1 - x;
					Data = pTemp[x*3];
					pTemp[x*3] = pTemp[xt*3];
					pTemp[xt*3] = Data;
					Data = pTemp[x*3+1];
					pTemp[x*3+1] = pTemp[xt*3+1];
					pTemp[xt*3+1] = Data;
					Data = pTemp[x*3+2];
					pTemp[x*3+2] = pTemp[xt*3+2];
					pTemp[xt*3+2] = Data;
					}
				break;
			case 32:
				for( x=0; x<xx; x++ ){
					xt = nWidth - 1 - x;
					Data = pTemp[x*4];
					pTemp[x*4] = pTemp[xt*4];
					pTemp[xt*4] = Data;
					Data = pTemp[x*4+1];
					pTemp[x*4+1] = pTemp[xt*4+1];
					pTemp[xt*4+1] = Data;
					Data = pTemp[x*4+2];
					pTemp[x*4+2] = pTemp[xt*4+2];
					pTemp[xt*4+2] = Data;
					Data = pTemp[x*4+3];
					pTemp[x*4+3] = pTemp[xt*4+3];
					pTemp[xt*4+3] = Data;
					}
				break;
			}
		}

	::GlobalUnlock( m_hDib );

	m_nLastError = IMAGELIB_SUCCESS;

	return( TRUE );

}

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;

	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 *CImageObject::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 CImageObject::SetPaletteCreationType( int nType )
{

	m_nPaletteCreationType = nType;

}

int CImageObject::GetPaletteCreationType( void )
{

	return( m_nPaletteCreationType );

}

RGBQUAD *CImageObject::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 *CImageObject::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 *CImageObject::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 CImageObject::GetPaletteBytes( void )
{

	return( m_nPaletteBytes );

}

HGLOBAL CImageObject::GetDib( void )
{

	return( m_hDib );

}

CPalette *CImageObject::GetPalette( void )
{

	return( &m_Palette );

}

LOGPALETTE *CImageObject::GetLogPal( void )
{

	return( m_pLogPal );

}

⌨️ 快捷键说明

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