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

📄 imageobject.cpp

📁 一些自己做的关于图象处理的程序(如傅立叶变换
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	
}

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 );
	
}

BOOL CImageObject::Crop( int nX1, int nY1, int nX2, int nY2 )
{
	
	NormalizeCoordinates( &nX1, &nY1, &nX2, &nY2 );
	
	if( nX2 - nX1 + 1 == m_nWidth && nY2 - nY1 + 1 == m_nHeight ) return( TRUE );
	
	unsigned char *pOldBuffer, *pNewBuffer;
	HGLOBAL hNewMemory;
	DWORD dwNewMemorySize;
	BITMAPFILEHEADER *pOldBFH, *pNewBFH;
	BITMAPINFOHEADER *pOldBIH, *pNewBIH;
	RGBQUAD *pOldPalette, *pNewPalette;
	unsigned char *pOldBits, *pNewBits, *pOldTemp, *pNewTemp;
	int nOldWidthBytes, nNewWidthBytes;
	int nNumColors, y, nPixelBytes;
	
	pOldBuffer = (unsigned char *) GetDIBPointer( &nOldWidthBytes, m_nBits, &nNewWidthBytes, nX2 - nX1 + 1 );
	if( pOldBuffer == NULL ) return( FALSE );
	
	pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
	pOldBIH = (BITMAPINFOHEADER *) &pOldBuffer[sizeof(BITMAPFILEHEADER)];
	nNumColors = m_nColors;
	pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
	pOldBits = (unsigned char *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
	
	dwNewMemorySize = (DWORD) nNumColors * sizeof( RGBQUAD ) + sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + nNewWidthBytes * ( nY2 - nY1 + 1 );
	m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
	hNewMemory = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewMemorySize );
	if( hNewMemory == NULL )
	{
		::GlobalUnlock( m_hDib );
		return( FALSE );
	}
	
	m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
	pNewBuffer = (unsigned char *) ::GlobalLock( hNewMemory );
	if( pNewBuffer == NULL )
	{
		::GlobalFree( hNewMemory );
		::GlobalUnlock( m_hDib );
		return( FALSE );
	}
	
	pNewBFH = (BITMAPFILEHEADER *) pNewBuffer;
	pNewBIH = (BITMAPINFOHEADER *) &pNewBuffer[sizeof(BITMAPFILEHEADER)];
	pNewPalette = (RGBQUAD *) &pNewBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
	pNewBits = (unsigned char *) &pNewBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
	
	*pNewBFH = *pOldBFH;
	*pNewBIH = *pOldBIH;
	pNewBIH->biSizeImage = 0;
	pNewBIH->biWidth = nX2 - nX1 + 1;
	pNewBIH->biHeight = nY2 - nY1 + 1;
	if( nNumColors != 0 ) memcpy( pNewPalette, pOldPalette, nNumColors * sizeof( RGBQUAD ) );
	
	nPixelBytes = 1;
	if( pOldBIH->biBitCount == 16 ) nPixelBytes = 2;
	else if( pOldBIH->biBitCount == 24 ) nPixelBytes = 3;
	else if( pOldBIH->biBitCount == 32 ) nPixelBytes = 4;
	
	for( y=0; y<pNewBIH->biHeight; y++ )
	{
		pOldTemp = pOldBits;
		pOldTemp += ( ( pOldBIH->biHeight - 1 - ( y + nY1 ) ) * nOldWidthBytes );
		pOldTemp += ( nPixelBytes *	nX1 );
		pNewTemp = pNewBits;
		pNewTemp += ( ( pNewBIH->biHeight - 1 - y ) * nNewWidthBytes );
		memcpy( pNewTemp, pOldTemp, nNewWidthBytes );
		pNewBIH->biSizeImage += nNewWidthBytes;
	}
	
	m_nWidth = pNewBIH->biWidth;
	m_nHeight = pNewBIH->biHeight;
	::GlobalUnlock( m_hDib );
	::GlobalUnlock( hNewMemory );
	::GlobalFree( m_hDib );
	m_hDib = hNewMemory;
	
	m_nLastError = IMAGELIB_SUCCESS;
	
	return( TRUE );
	
}

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;
	}
	
}

BOOL CImageObject::Stretch( int nNewWidth, int nNewHeight )
{
	
	if( nNewWidth == m_nWidth && nNewHeight == m_nHeight ) return( TRUE );
	
	unsigned char *pOldBuffer, *pNewBuffer, *pOldTemp, *pNewTemp;
	HGLOBAL hNewMemory;
	DWORD dwNewMemorySize;
	BITMAPFILEHEADER *pOldBFH, *pNewBFH;
	BITMAPINFOHEADER *pOldBIH, *pNewBIH;
	RGBQUAD *pOldPalette, *pNewPalette;
	unsigned char *pOldBits, *pNewBits;
	int nOldWidthBytes, nNewWidthBytes;
	int nNumColors;
	int x, y, xx, yy;
	unsigned char Data;
	
	pOldBuffer = (unsigned char *) GetDIBPointer( &nOldWidthBytes, m_nBits, &nNewWidthBytes, nNewWidth );
	if( pOldBuffer == NULL ) return( FALSE );
	
	pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
	pOldBIH = (BITMAPINFOHEADER *) &pOldBuffer[sizeof(BITMAPFILEHEADER)];
	nNumColors = m_nColors;
	pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
	pOldBits = (unsigned char *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
	
	dwNewMemorySize = (DWORD) nNumColors * sizeof( RGBQUAD ) + sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + nNewWidthBytes * nNewHeight;
	m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
	hNewMemory = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewMemorySize );
	if( hNewMemory == NULL ){
		::GlobalUnlock( m_hDib );
		return( FALSE );
	}
	
	m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
	pNewBuffer = (unsigned char *) ::GlobalLock( hNewMemory );
	if( pNewBuffer == NULL ){
		::GlobalFree( hNewMemory );
		::GlobalUnlock( m_hDib );
		return( FALSE );
	}
	
	pNewBFH = (BITMAPFILEHEADER *) pNewBuffer;
	pNewBIH = (BITMAPINFOHEADER *) &pNewBuffer[sizeof(BITMAPFILEHEADER)];
	pNewPalette = (RGBQUAD *) &pNewBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
	pNewBits = (unsigned char *) &pNewBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
	
	*pNewBFH = *pOldBFH;
	*pNewBIH = *pOldBIH;
	pNewBIH->biSizeImage = nNewWidthBytes * nNewHeight;
	pNewBIH->biWidth = nNewWidth;
	pNewBIH->biHeight = nNewHeight;
	if( nNumColors != 0 ) memcpy( pNewPalette, pOldPalette, nNumColors * sizeof( RGBQUAD ) );
	
	m_nWidth = nNewWidth;
	m_nHeight = nNewHeight;
	
	switch( m_nBits ){
	case 1:
		for( y=0; y<nNewHeight; y++ ){
			yy = ( pOldBIH->biHeight * y ) / nNewHeight;
			pOldTemp = pOldBits;
			pOldTemp += ( ( pOldBIH->biHeight - 1 - yy ) * nOldWidthBytes );
			pNewTemp = pNewBits;
			pNewTemp += ( ( nNewHeight - 1 - y ) * nNewWidthBytes );
			for( x=0; x<nNewWidth; x++ ){
				xx = ( pOldBIH->biWidth * x ) / nNewWidth;
				Data = pOldTemp[xx/8];
				Data >>= ( 7 - ( xx & 7 ) );
				Data &= 0x01;
				Data <<= ( 7 - ( x & 7 ) );
				pNewTemp[x/8] |= Data;
			}
		}
		break;
	case 4:
		for( y=0; y<nNewHeight; y++ ){
			yy = ( pOldBIH->biHeight * y ) / nNewHeight;
			pOldTemp = pOldBits;
			pOldTemp += ( ( pOldBIH->biHeight - 1 - yy ) * nOldWidthBytes );
			pNewTemp = pNewBits;
			pNewTemp += ( ( nNewHeight - 1 - y ) * nNewWidthBytes );
			for( x=0; x<nNewWidth; x++ ){
				xx = ( pOldBIH->biWidth * x ) / nNewWidth;
				Data = pOldTemp[xx/2];
				if( !( xx & 1 ) ) Data >>= 4;
				else Data &= 0x0f;
				if( !( x & 1 ) ) Data <<= 4;
				pNewTemp[x/2] |= Data;
			}
		}
		break;
	case 8:
		for( y=0; y<nNewHeight; y++ ){
			yy = ( pOldBIH->biHeight * y ) / nNewHeight;
			pOldTemp = pOldBits;
			pOldTemp += ( ( pOldBIH->biHeight - 1 - yy ) * nOldWidthBytes );
			pNewTemp = pNewBits;
			pNewTemp += ( ( nNewHeight - 1 - y ) * nNewWidthBytes );
			for( x=0; x<nNewWidth; x++ ){
				xx = ( pOldBIH->biWidth * x ) / nNewWidth;
				pNewTemp[x] = pOldTemp[xx];
			}
		}
		break;
	case 16:
		for( y=0; y<nNewHeight; y++ ){
			yy = ( pOldBIH->biHeight * y ) / nNewHeight;
			pOldTemp = pOldBits;
			pOldTemp += ( ( pOldBIH->biHeight - 1 - yy ) * nOldWidthBytes );
			pNewTemp = pNewBits;
			pNewTemp += ( ( nNewHeight - 1 - y ) * nNewWidthBytes );
			for( x=0; x<nNewWidth; x++ ){
				xx = ( pOldBIH->biWidth * x ) / nNewWidth;
				pNewTemp[x*2] = pOldTemp[xx*2];
				pNewTemp[x*2+1] = pOldTemp[xx*2+1];
			}
		}
		break;
	case 24:
		for( y=0; y<nNewHeight; y++ ){
			yy = ( pOldBIH->biHeight * y ) / nNewHeight;
			pOldTemp = pOldBits;
			pOldTemp += ( ( pOldBIH->biHeight - 1 - yy ) * nOldWidthBytes );
			pNewTemp = pNewBits;
			pNewTemp += ( ( nNewHeight - 1 - y ) * nNewWidthBytes );
			for( x=0; x<nNewWidth; x++ ){
				xx = ( pOldBIH->biWidth * x ) / nNewWidth;
				pNewTemp[x*3] = pOldTemp[xx*3];
				pNewTemp[x*3+1] = pOldTemp[xx*3+1];
				pNewTemp[x*3+2] = pOldTemp[xx*3+2];
			}
		}
		break;
	case 32:
		for( y=0; y<nNewHeight; y++ ){
			yy = ( pOldBIH->biHeight * y ) / nNewHeight;
			pOldTemp = pOldBits;
			pOldTemp += ( ( pOldBIH->biHeight - 1 - yy ) * nOldWidthBytes );
			pNewTemp = pNewBits;
			pNewTemp += ( ( nNewHeight - 1 - y ) * nNewWidthBytes );
			for( x=0; x<nNewWidth; x++ ){
				xx = ( pOldBIH->biWidth * x ) / nNewWidth;
				pNewTemp[x*4] = pOldTemp[xx*4];
				pNewTemp[x*4+1] = pOldTemp[xx*4+1];
				pNewTemp[x*4+2] = pOldTemp[xx*4+2];
				pNewTemp[x*4+3] = pOldTemp[xx*4+3];
			}
		}
		break;
	}
	
	::GlobalUnlock( m_hDib );
	::GlobalUnlock( hNewMemory );
	::GlobalFree( m_hDib );
	m_hDib = hNewMemory;
	
	m_nLastError = IMAGELIB_SUCCESS;
	
	return( 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 CImageObject::Rotate( int nDegrees )
{
	
	m_nLastError = IMAGELIB_HDIB_NULL;
	if( m_hDib == NULL ) return( FALSE );
	
	m_nLastError = IMAGELIB_ROTATE_ERROR;
	switch( nDegrees ){
	case 90:
		if( !RotateIt( nDegrees ) ) return( FALSE );
		break;
	case 180:
		if( !Invert() ) return( FALSE );
		if( !Reverse() ) return( FALSE );
		break;
	case 270:
		if( !RotateIt( nDegrees ) ) return( FALSE );
		break;
	default:
		m_nLastError = IMAGELIB_ROTATION_VALUE_ERROR;
		return( FALSE );
	}
	
	m_nLastError = IMAGELIB_SUCCESS;
	
	return( TRUE );
	
}

BOOL CImageObject::RotateIt( int nDegrees )
{
	
	int nNewWidth, nNewHeight;
	nNewWidth = m_nHeight;
	nNewHeight = m_nWidth;
	
	unsigned char *pOldBuffer, *pNewBuffer;
	HGLOBAL hNewMemory;
	DWORD dwNewMemorySize;

⌨️ 快捷键说明

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