📄 image.cpp
字号:
// Image.cpp: implementation of the CImage class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Image.h"
#include "BmpCoder.h"
#include "ColorPixel.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define PALVERSION 0x300
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CImage::CImage()
{
m_bValidate = FALSE;
m_sizeImage = CSize(0,0);
m_nUsedColor = 0;
m_dwLineLen = 0;
m_pBuf = NULL;
m_PixelPtr = NULL;
m_ColorPtr = NULL;
m_pPal = NULL;
}
CImage::CImage( LPCTSTR lpszPathname )
{
m_bValidate = FALSE;
m_sizeImage = CSize(0,0);
m_nUsedColor = 0;
m_dwLineLen = 0;
m_pBuf = NULL;
m_PixelPtr = NULL;
m_ColorPtr = NULL;
m_pPal = NULL;
if( !LoadImage( lpszPathname ) )
{
m_strError = "File Decode Error.";
m_bValidate = FALSE;
}
else
m_bValidate = TRUE;
}
CImage::CImage( CSize size, int mode, int ivalue )
{
m_bValidate = FALSE;
m_sizeImage = CSize(0,0);
m_nUsedColor = 0;
m_dwLineLen = 0;
m_pBuf = NULL;
m_PixelPtr = NULL;
m_ColorPtr = NULL;
m_pPal = NULL;
m_bValidate = CreateImage( size, mode, ivalue );
if( m_nColorMode == INDEXED )
CreatePalette();
}
CImage::CImage( CImage* pImage )
{
m_bValidate = FALSE;
m_sizeImage = CSize(0,0);
m_nUsedColor = 0;
m_dwLineLen = 0;
m_pBuf = NULL;
m_PixelPtr = NULL;
m_ColorPtr = NULL;
m_pPal = NULL;
m_bValidate = CreateImage( pImage->m_sizeImage, pImage->m_nColorMode, 0 );
if( m_bValidate )
{
DWORD dwSize;
BYTE* pDes;
BYTE* pSrc;
if( pImage->m_nColorMode == INDEXED )
{
pDes = m_pDib-1024;
pSrc = pImage->m_pDib-1024;
dwSize = pImage->m_dwLineLen * pImage->m_sizeImage.cy + 1024;
}
else
{
pDes = m_pDib;
pSrc = pImage->m_pDib;
dwSize = pImage->m_dwLineLen * pImage->m_sizeImage.cy;
}
memcpy( pDes, pSrc, dwSize );
}
m_nImageType = pImage->m_nImageType;
m_nUsedColor = pImage->m_nUsedColor;
if( m_nColorMode == INDEXED )
CreatePalette();
}
CImage::~CImage()
{
if( m_pBuf ) DeleteImage();
if( m_pPal ) delete m_pPal;
}
BOOL CImage::CreateImage( CSize size, int mode, int ivalue )
{
if( m_pBuf ) DeleteImage();
LPBITMAPINFOHEADER bmpInfoHeader;
DWORD dwSizeImage;
int i;
BYTE *lpPal;
dwSizeImage = size.cy*(DWORD)((size.cx*mode/8+3)&~3);
if( mode == TRUERGB )
m_pBuf = new BYTE[sizeof(BITMAPINFOHEADER)+dwSizeImage];
else
m_pBuf = new BYTE[sizeof(BITMAPINFOHEADER)+dwSizeImage+1024];
if( !m_pBuf )
{
m_strError = "Memory Allocation Error.";
return FALSE;
}
bmpInfoHeader = (LPBITMAPINFOHEADER)m_pBuf;
bmpInfoHeader->biSize = sizeof(BITMAPINFOHEADER) ;
bmpInfoHeader->biWidth = size.cx;
bmpInfoHeader->biHeight = size.cy;
bmpInfoHeader->biPlanes = 1;
bmpInfoHeader->biBitCount = mode;
bmpInfoHeader->biCompression = BI_RGB ;
bmpInfoHeader->biSizeImage = dwSizeImage;
bmpInfoHeader->biXPelsPerMeter = 0 ;
bmpInfoHeader->biYPelsPerMeter = 0 ;
bmpInfoHeader->biClrUsed = 0 ;
bmpInfoHeader->biClrImportant = 0 ;
lpPal = (BYTE*)m_pBuf+sizeof(BITMAPINFOHEADER);
if ( mode == INDEXED )
{
bmpInfoHeader->biClrUsed = 256;
DWORD offDest = 0;
for( i = 0 ; i < 256 ; i++ )
{
lpPal[offDest++] = (BYTE)i;
lpPal[offDest++] = (BYTE)i;
lpPal[offDest++] = (BYTE)i;
lpPal[offDest++] = 0x00;
}
}
m_sizeImage = size;
m_nColorMode = mode;
m_dwLineLen = (m_sizeImage.cx*m_nColorMode/8+3)&~3;
if( m_nColorMode == TRUERGB )
{
m_pDib = (BYTE*)(m_pBuf + *(LPDWORD)m_pBuf);
DWORD l = m_dwLineLen*m_sizeImage.cy/3;
CColorPixel* ptr = (CColorPixel*)m_pDib;
for( i = 0 ; i < (int)l ; i++ )
ptr[i] = ivalue;
m_nUsedColor = 0;
}
else
{
m_pDib = (BYTE*)(m_pBuf + *(LPDWORD)m_pBuf + 1024);
memset( m_pDib, ivalue, m_dwLineLen*m_sizeImage.cy );
m_nUsedColor = 256;
}
AllocPtr();
return TRUE;
}
void CImage::DeleteImage()
{
if( !m_pBuf ) return;
FreePtr();
delete [] m_pBuf;
m_pBuf = NULL;
}
BOOL CImage::AllocPtr()
{
int i;
if( m_nColorMode == INDEXED )
{
if( m_PixelPtr ) FreePtr();
m_PixelPtr = new BYTE*[m_sizeImage.cy];
if( !m_PixelPtr ) return FALSE;
for( i = 1 ; i <= m_sizeImage.cy ; i++ )
m_PixelPtr[i-1] = m_pDib+(m_sizeImage.cy-i)*m_dwLineLen;
}
else if( m_nColorMode == TRUERGB )
{
if( m_ColorPtr ) FreePtr();
m_ColorPtr = new CColorPixel*[m_sizeImage.cy];
if( !m_ColorPtr ) return FALSE;
for( i = 1 ; i <= m_sizeImage.cy ; i++ )
m_ColorPtr[i-1] = (CColorPixel*)(m_pDib+(m_sizeImage.cy-i)*m_dwLineLen);
}
return TRUE;
}
void CImage::FreePtr()
{
if( m_nColorMode == INDEXED )
{
if( m_PixelPtr )
{
delete [] m_PixelPtr;
m_PixelPtr = NULL;
}
}
else if( m_nColorMode == TRUERGB )
{
if( m_ColorPtr )
{
delete [] m_ColorPtr;
m_ColorPtr = NULL;
}
}
}
BOOL CImage::CreatePalette()
{
if( m_nColorMode == TRUERGB ) return FALSE;
BYTE* pBuf = new BYTE[sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*256];
if( !pBuf )
{
m_strError = "Palette Momory Allocation Error.";
return FALSE;
}
LPLOGPALETTE lpPal = (LPLOGPALETTE)pBuf;
lpPal->palVersion = PALVERSION;
lpPal->palNumEntries = 256;
// 漠扼荐父怒 迫饭飘甫 迫饭飘 浚飘府俊 持绰促.
//LPBITMAPINFO bmpInfo = (LPBITMAPINFO)m_pBuf;
LPPALETTEENTRY pPal = (LPPALETTEENTRY)(m_pBuf+sizeof(BITMAPINFOHEADER));
for(int i = 0 ; i < m_nUsedColor ; i++ )
{
lpPal->palPalEntry[i].peRed = pPal[i].peRed;
lpPal->palPalEntry[i].peGreen = pPal[i].peGreen;
lpPal->palPalEntry[i].peBlue = pPal[i].peBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
// CPalette 备炼眉俊 lpPal甫 傅农矫难辑 迫饭飘甫 父电促.
if( m_pPal ) delete m_pPal;
m_pPal = new CPalette;
m_pPal->CreatePalette( lpPal );
delete [] pBuf;
return TRUE;
}
BOOL CImage::LoadImage( LPCTSTR lpszPathname )
{
CString filetype;
filetype = lpszPathname;
filetype.MakeUpper();
m_strPathname = lpszPathname;
BOOL res = FALSE;
if( filetype.Find(".BMP") > -1 )
{
m_nImageType = BMP;
CBmpCoder bmpCoder(this);
m_bValidate = bmpCoder.DoDecode();
}
else
m_bValidate = FALSE;
return m_bValidate;
}
BOOL CImage::SaveImage( LPCTSTR lpszPathname )
{
if( !m_bValidate ) return FALSE;
CString filetype;
filetype = lpszPathname;
filetype.MakeUpper();
m_strPathname = lpszPathname;
if( filetype.Find(".BMP") > -1 )
{
m_nImageType = BMP;
CBmpCoder bmpCoder(this);
return bmpCoder.DoEncode();
}
else
return FALSE;
}
void CImage::Paint( CDC* pDC, int mode )
{
Paint( pDC, CPoint(0,0), mode );
}
void CImage::Paint( CDC* pDC, CPoint des, int mode )
{
if( !m_bValidate ) return;
LPSTR lpDIBBits;
BOOL bSuccess = FALSE;
LPBITMAPINFO bmpInfo;
CPalette* pPal = NULL;
lpDIBBits = (LPSTR)m_pDib;
bmpInfo = (LPBITMAPINFO)m_pBuf;
if( m_nColorMode == INDEXED && m_pPal )
{
pPal = pDC->SelectPalette( m_pPal, TRUE );
pDC->RealizePalette();
}
::SetDIBitsToDevice( pDC->m_hDC, // hDC
0, // DestX
0, // DestY
m_sizeImage.cx, // nDestWidth
m_sizeImage.cy, // nDestHeight
0, // SrcX
0, // SrcY
0, // nStartScan
(WORD)m_sizeImage.cy, // nNumScans
lpDIBBits, // lpBits
bmpInfo, // lpBitsInfo
DIB_RGB_COLORS ); // wUsage
if( pPal )
pDC->SelectPalette( pPal, TRUE );
}
void CImage::Paint( CDC* pDC, CSize dessize, int mode )
{
Paint( pDC, CPoint(0,0), dessize, CPoint(0,0), m_sizeImage, mode );
}
void CImage::Paint( CDC* pDC, CPoint des, CSize dessize, int mode )
{
Paint( pDC, des, dessize, CPoint(0,0), m_sizeImage, mode );
}
void CImage::Paint( CDC* pDC, CPoint des, CSize dessize, CPoint src, int mode )
{
Paint( pDC, des, dessize, src, m_sizeImage, mode );
}
void CImage::Paint( CDC* pDC, CPoint des, CSize dessize, CPoint src, CSize srcsize, int mode )
{
if( !m_bValidate ) return;
LPSTR lpDIBBits;
BOOL bSuccess = FALSE;
LPBITMAPINFO bmpInfo;
CPalette* pPal = NULL;
lpDIBBits = (LPSTR)m_pDib;
bmpInfo = (LPBITMAPINFO)m_pBuf;
CDC MemDC;
MemDC.CreateCompatibleDC( pDC );
CBitmap bmScreen;
bmScreen.CreateCompatibleBitmap( pDC, dessize.cx, dessize.cy );
CBitmap* pBitmap = MemDC.SelectObject( &bmScreen );
if( m_nColorMode == INDEXED && m_pPal )
{
pPal = MemDC.SelectPalette( m_pPal, TRUE );
MemDC.RealizePalette();
}
::SetStretchBltMode( MemDC.m_hDC , COLORONCOLOR );
::StretchDIBits( MemDC.m_hDC, // hDC
0, // DestX
0, // DestY
dessize.cx, // nDestWidth
dessize.cy, // nDestHeight
src.x, // SrcX
src.y, // SrcY
srcsize.cx, // SrcWidth
srcsize.cy, // SrcHeight
lpDIBBits, // lpBits
bmpInfo, // lpBitsInfo
DIB_RGB_COLORS, SRCCOPY );// wUsage
if( pPal )
MemDC.SelectPalette( pPal, TRUE );
if( m_nColorMode == INDEXED && m_pPal )
{
pPal = pDC->SelectPalette( m_pPal, TRUE );
pDC->RealizePalette();
}
pDC->BitBlt( des.x, des.y, dessize.cx, dessize.cy , &MemDC, 0, 0, mode );
MemDC.SelectObject( pBitmap );
if( pPal )
pDC->SelectPalette( pPal, TRUE );
}
BOOL CImage::IsGray()
{
if( !m_bValidate ) return FALSE;
if( m_nColorMode == TRUERGB || !m_pPal ) return FALSE;
LPPALETTEENTRY pPal = (LPPALETTEENTRY)(m_pBuf+sizeof(BITMAPINFOHEADER));
int n = 255;
int i;
BOOL res = TRUE;
for( i = 0 ; i < n ; i++ )
{
if( pPal[i].peRed != pPal[i].peGreen || pPal[i].peGreen != pPal[i].peBlue )
{
res = FALSE;
break;
}
}
return res;
}
void CImage::operator = ( CImage& Image )
{
if( !Image.m_bValidate ) return;
if( m_pBuf ) DeleteImage();
m_bValidate = CreateImage( Image.m_sizeImage, Image.m_nColorMode, 0 );
if( m_bValidate )
{
DWORD dwSize;
BYTE* pDes;
BYTE* pSrc;
if( Image.m_nColorMode == INDEXED )
{
pDes = m_pDib-1024;
pSrc = Image.m_pDib-1024;
dwSize = Image.m_dwLineLen * Image.m_sizeImage.cy + 1024;
}
else
{
pDes = m_pDib;
pSrc = Image.m_pDib;
dwSize = Image.m_dwLineLen * Image.m_sizeImage.cy;
}
memcpy( pDes, pSrc, dwSize );
}
m_nImageType = Image.m_nImageType;
m_nUsedColor = Image.m_nUsedColor;
if( m_nColorMode == INDEXED )
CreatePalette();
}
CSize CImage::GetImageSize()
{
return m_sizeImage;
}
int CImage::GetXSize()
{
return m_sizeImage.cx;
}
int CImage::GetYSize()
{
return m_sizeImage.cy;
}
BYTE** CImage::GetPtr()
{
return m_PixelPtr;
}
CColorPixel** CImage::GetColorPtr()
{
return m_ColorPtr;
}
RGBQUAD* CImage::GetPalPtr()
{
return (RGBQUAD*)(m_pBuf+sizeof(BITMAPINFOHEADER));
}
BOOL CImage::CopyPalette(CImage* pImage)
{
if( !m_bValidate || !pImage || !pImage->m_bValidate ) return FALSE;
RGBQUAD* src = (RGBQUAD*)(pImage->m_pBuf+sizeof(BITMAPINFOHEADER));
RGBQUAD* des = (RGBQUAD*)(m_pBuf+sizeof(BITMAPINFOHEADER));
memcpy( des, src, sizeof(RGBQUAD)*256 );
return CreatePalette();
}
BOOL CImage::UpdatePalette()
{
return CreatePalette();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -