📄 imageobject.cpp
字号:
// ImageObject.cpp
#include "stdafx.h"
#include "ImageObject.h"
char *CImageObject::szExtensions[] = { ".BMP", ".GIF", ".PCX", ".TGA", ".JPG", ".TIF", "" };
CImageObject::CImageObject()
{
InitVars();
}
CImageObject::CImageObject( const char *pszFilename, CDC *pDC, int nX, int nY )
{
InitVars();
Load( pszFilename, pDC, nX, nY );
}
CImageObject::~CImageObject()
{
if( m_hDib ) ::GlobalFree( m_hDib );
if( m_pszFilename != NULL ) delete [] m_pszFilename;
}
void CImageObject::InitVars( BOOL bFlag )
{
m_nWidth = m_nHeight = m_nBits = m_nColors = m_nImageType = 0;
m_nX = m_nY = 0;
m_nLastError = 0;
m_hDib = NULL;
m_nPaletteCreationType = FIXED_PALETTE;
if( !bFlag )
{
m_pszFilename = NULL;
m_pLogPal = NULL;
}
m_nQuality = 50;
}
BOOL CImageObject::Load( const char *pszFilename, CDC *pDC, int nX, int nY )
{
m_nImageType = FileType( pszFilename );
if( m_nImageType == 0 )
{
m_nLastError = IMAGELIB_UNSUPPORTED_FILETYPE;
return( FALSE );
}
KillImage();
m_pszFilename = new char[strlen(pszFilename)+1];
if( m_pszFilename != NULL )
{
strcpy( m_pszFilename, pszFilename );
}
switch( m_nImageType )
{
case IMAGETYPE_BMP:
m_hDib = ::LoadBMP( pszFilename );
if( m_hDib == NULL )
{
m_nLastError = ::GetLastPicLibError();
return( FALSE );
}
break;
case IMAGETYPE_GIF:
m_hDib = ::LoadGIF( pszFilename );
if( m_hDib == NULL )
{
m_nLastError = ::GetLastPicLibError();
return( FALSE );
}
break;
case IMAGETYPE_JPG:
m_hDib = ::LoadJPG( pszFilename );
if( m_hDib == NULL )
{
m_nLastError = ::GetLastPicLibError();
return( FALSE );
}
break;
case IMAGETYPE_PCX:
m_hDib = ::LoadPCX( pszFilename );
if( m_hDib == NULL )
{
m_nLastError = ::GetLastPicLibError();
return( FALSE );
}
break;
case IMAGETYPE_TGA:
m_hDib = ::LoadTGA( pszFilename );
if( m_hDib == NULL )
{
m_nLastError = ::GetLastPicLibError();
return( FALSE );
}
break;
case IMAGETYPE_TIF:
m_hDib = ::LoadTIF( pszFilename );
if( m_hDib == NULL )
{
m_nLastError = ::GetLastPicLibError();
return( FALSE );
}
break;
}
ProcessImageHeader();
ProcessPalette();
if( pDC != NULL )
{
Draw( pDC, nX, nY );
}
return( TRUE );
}
BOOL CImageObject::GetImageInfo( const char *pszFilename, int *pnWidth, int *pnHeight, int *pnPlanes, int *pnBitsPerPixel, int *pnNumColors )
{
int nImageType;
nImageType = FileType( pszFilename );
if( nImageType == 0 )
{
m_nLastError = IMAGELIB_UNSUPPORTED_FILETYPE;
return( FALSE );
}
switch( nImageType )
{
case IMAGETYPE_BMP:
return( ::GetBMPInfo( pszFilename, pnWidth, pnHeight, pnPlanes, pnBitsPerPixel, pnNumColors ) );
case IMAGETYPE_GIF:
return( ::GetGIFInfo( pszFilename, pnWidth, pnHeight, pnPlanes, pnBitsPerPixel, pnNumColors ) );
case IMAGETYPE_JPG:
return( ::GetJPGInfo( pszFilename, pnWidth, pnHeight, pnPlanes, pnBitsPerPixel, pnNumColors ) );
case IMAGETYPE_PCX:
return( ::GetPCXInfo( pszFilename, pnWidth, pnHeight, pnPlanes, pnBitsPerPixel, pnNumColors ) );
case IMAGETYPE_TGA:
return( ::GetTGAInfo( pszFilename, pnWidth, pnHeight, pnPlanes, pnBitsPerPixel, pnNumColors ) );
case IMAGETYPE_TIF:
return( ::GetTIFInfo( pszFilename, pnWidth, pnHeight, pnPlanes, pnBitsPerPixel, pnNumColors ) );
}
return( FALSE );
}
int CImageObject::GetLastError( void )
{
return( m_nLastError );
}
BOOL CImageObject::Save( const char *pszFilename, int nType )
{
if( nType == -1 ) nType = ExtensionIndex( pszFilename );
if( nType < IMAGETYPE_FIRSTTYPE || nType > IMAGETYPE_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 IMAGETYPE_BMP:
return( ::SaveBMP( pszFilename, m_hDib ) );
break;
case IMAGETYPE_GIF:
return( ::SaveGIF( pszFilename, m_hDib ) );
break;
case IMAGETYPE_JPG:
return( ::SaveJPG( pszFilename, m_hDib, m_nQuality ) );
break;
case IMAGETYPE_PCX:
return( ::SavePCX( pszFilename, m_hDib ) );
break;
case IMAGETYPE_TGA:
return( ::SaveTGA( pszFilename, m_hDib ) );
break;
case IMAGETYPE_TIF:
return( ::SaveTIF( pszFilename, m_hDib ) );
break;
}
return( TRUE );
}
int CImageObject::ExtensionIndex( const char *pszFilename )
{
int Index = 0;
char *pszExtension;
pszExtension = (char *) &pszFilename[strlen(pszFilename)-4];
while( szExtensions[Index][0] )
{
if( !stricmp( pszExtension, szExtensions[Index] ) ) return( Index + 1 );
Index++;
}
return( -1 );
}
int CImageObject::GetWidth( void )
{
return( m_nWidth );
}
int CImageObject::GetHeight( void )
{
return( m_nHeight );
}
int CImageObject::GetNumBits( void )
{
return( m_nBits );
}
int CImageObject::GetNumColors( void )
{
return( m_nColors );
}
BOOL CImageObject::GetPaletteData( RGBQUAD *pRGBPalette )
{
m_nLastError = IMAGELIB_HDIB_NULL;
if( m_hDib == NULL ) return( FALSE );
char *pTemp;
pTemp = (char *) ::GlobalLock( m_hDib );
m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
if( pTemp == NULL ) return( FALSE );
memcpy( pRGBPalette, &pTemp[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)], m_nPaletteBytes );
m_nLastError = IMAGELIB_SUCCESS;
::GlobalUnlock( m_hDib );
return( TRUE );
}
RGBQUAD *CImageObject::GetPaletteData( void )
{
m_nLastError = IMAGELIB_HDIB_NULL;
if( m_hDib == NULL ) return( NULL );
m_nLastError = IMAGELIB_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 = IMAGELIB_MEMORY_ALLOCATION_ERROR;
return( NULL );
}
char *pTemp;
pTemp = (char *) ::GlobalLock( m_hDib );
m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
if( pTemp == NULL ){
delete [] pRGBPalette;
return( NULL );
}
memcpy( pRGBPalette, &pTemp[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)], m_nColors * sizeof( RGBQUAD ) );
m_nLastError = IMAGELIB_SUCCESS;
::GlobalUnlock( m_hDib );
return( pRGBPalette );
}
int CImageObject::GetImageType( const char *pFilename )
{
return( ::FileType( pFilename ) );
}
int CImageObject::GetImageType( void )
{
return( m_nImageType );
}
BOOL CImageObject::Draw( CDC *pDC, int nX, int nY )
{
if( nX != -1 ) m_nX = nX;
if( nY != -1 ) m_nY = nY;
m_nLastError = IMAGELIB_HDIB_NULL;
if( m_hDib == NULL ) return( FALSE );
char *pTemp;
pTemp = (char *) ::GlobalLock( m_hDib );
m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
if( pTemp == NULL ) return( NULL );
BITMAPINFOHEADER *pBIH;
pBIH = (BITMAPINFOHEADER *) &pTemp[sizeof(BITMAPFILEHEADER)];
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_nPaletteBytes],
(BITMAPINFO *) pBIH, DIB_RGB_COLORS, SRCCOPY );
::GlobalUnlock( m_hDib );
m_nLastError = IMAGELIB_STRETCHDIBITS_ERROR;
if( nRet != m_nHeight ) return( FALSE );
m_nLastError = IMAGELIB_SUCCESS;
return( TRUE );
}
LOGPALETTE *CImageObject::CreateLogPalette( RGBQUAD *pPalette, int nNumColors )
{
LOGPALETTE *pLogPal;
int i;
if( pPalette == NULL ) return( NULL );
pLogPal = (LOGPALETTE *) new char [sizeof(LOGPALETTE)+nNumColors*sizeof(PALETTEENTRY)];
if( pLogPal == NULL ) return( NULL );
pLogPal->palVersion = 0x300;
pLogPal->palNumEntries = (unsigned short) nNumColors;
for( i=0; i<nNumColors; i++ ){
pLogPal->palPalEntry[i].peRed = pPalette[i].rgbRed;
pLogPal->palPalEntry[i].peGreen = pPalette[i].rgbGreen;
pLogPal->palPalEntry[i].peBlue = pPalette[i].rgbBlue;
pLogPal->palPalEntry[i].peFlags = 0;
}
return( pLogPal );
}
void CImageObject::ProcessImageHeader( void )
{
m_nLastError = IMAGELIB_HDIB_NULL;
if( m_hDib == NULL ) return;
char *pTemp;
BITMAPINFOHEADER *pBIH;
pTemp = (char *) ::GlobalLock( m_hDib );
m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
if( pTemp == NULL ) return;
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;
// if(pBIH->biCompression==BI_RGB) AfxMessageBox("BI_RGB");
// if(pBIH->biCompression!=BI_RGB) AfxMessageBox("BI_RLE8");
/*
该程序在处理BMP压缩图象时,要出问题,因Windows本身可以正确显示
BMP类型的压缩图象,所以该程序在载入部分和显示部分没有考虑压缩图
象的问题,却依然能够正确地显示图象。但在做图象处理的时候,则不能
访问到正确的像素值。
*/
if( m_nPlanes > 1 ) m_nColors <<= ( m_nPlanes - 1 );
if( m_nBits >= 16 ) m_nColors = 0;
DWORD dwSize=m_nHeight*WidthBytes(m_nBits,m_nWidth);
pBIH->biSizeImage = dwSize;
::GlobalUnlock( m_hDib );
m_nLastError = IMAGELIB_SUCCESS;
}
void CImageObject::ProcessPalette( void )
{
m_nLastError = IMAGELIB_HDIB_NULL;
if( m_hDib == NULL ) return;
CWindowDC WindowDC( NULL );
m_nScreenPlanes = WindowDC.GetDeviceCaps( PLANES );
m_nScreenBits = WindowDC.GetDeviceCaps( BITSPIXEL );
m_nPaletteBytes = 0;
m_Palette.DeleteObject();
if( m_nBits <= 8 ) m_nPaletteBytes = m_nColors * sizeof( RGBQUAD );
if( m_nScreenBits >= 16 ) return;
char *pTemp;
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 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 CImageObject::IsLoaded( void )
{
return( m_hDib != NULL );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -