📄 core_graphics.cpp
字号:
/**************************************************
图像处理和DirectDraw主干模块
Author: LittleFish QQ:93663886
E-Mail: kittyfish_1981@yahoo.com.cn
Blog: http://blog.csdn.net/kittyfish
真诚的期待你提出改良方法或程序BUG
**************************************************/
#include "Core_Graphics.h"
///////////////Global Var///////////////////////////////////////////
cDirectDraw* g_pDirectDraw = NULL;
////////////////////////////////////////////////////////////////////
cGraphics::cGraphics()
{
m_lpDDS = NULL;
m_bColorKey = FALSE;
}
cGraphics::cGraphics( int width, int height )
{
Create( width, height );
m_bColorKey = FALSE;
}
cGraphics::~cGraphics()
{
Release(); //
}
BOOL cGraphics::Create( int width, int height )
{
DDSURFACEDESC2 ddsd;
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
ddsd.dwHeight = height;
ddsd.dwWidth = width;
HRESULT hr;
hr = g_pDirectDraw->GetDirectDraw()->CreateSurface( &ddsd, (LPDIRECTDRAWSURFACE7*)&m_lpDDS, NULL );
m_iHeight = height;
m_iWidth = width;
if( DD_OK == hr )
return TRUE;
return FALSE;
}
BOOL cGraphics::CreateFromBitmap( TCHAR* bmpFileName )
{
if( bmpFileName == NULL )
return FALSE;
HBITMAP hBmp;
hBmp = ( HBITMAP )LoadImage( GetModuleHandle(NULL), bmpFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
if( hBmp == NULL )
{
int errCode = GetLastError();
if( errCode == 2 )
{
DebugMB( _T("cGraphics::CreateFromBitmap:[%s]\nImageFile[%s]"), _T("没有找到你要的图片!"), bmpFileName );
}
else if( errCode == 8 )
{
DebugMB( _T("cGraphics::CreateFromBitmap:[%s]\nImageFile[%s]"), _T("内存不足!"), bmpFileName );
}
return FALSE;
}
HDC hdcBitmap; // memory DC
hdcBitmap = CreateCompatibleDC( NULL );
SelectObject( hdcBitmap, hBmp );
BITMAP bmp;
GetObject( hBmp, sizeof(BITMAP), &bmp );
DeleteObject( hBmp );
m_iWidth = bmp.bmWidth;
m_iHeight = bmp.bmHeight;
Release();
if( !Create( m_iWidth, m_iHeight ) )
{
DeleteDC( hdcBitmap );
return FALSE;
}
HRESULT hr;
HDC hdc;
hr = m_lpDDS->GetDC( &hdc );
if( hr == DD_OK )
{
StretchBlt( hdc,0, 0, m_iWidth, m_iHeight, hdcBitmap, 0, 0, m_iWidth, m_iHeight, SRCCOPY );
m_lpDDS->ReleaseDC( hdc );
}
else
{
DeleteDC( hdcBitmap );
return FALSE;
}
DeleteDC( hdcBitmap );
return TRUE;
}
BOOL cGraphics::Load( TCHAR* bmpFileName )
{
if( bmpFileName == NULL )
return FALSE;
HBITMAP hBmp;
hBmp = ( HBITMAP )LoadImage( GetModuleHandle(NULL), bmpFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
if( hBmp == NULL )
{
int errCode = GetLastError();
if( errCode == 2 )
{
DebugMB( _T("cGraphics::CreateFromBitmap:[%s]\nImageFile[%s]"), _T("没有找到你要的图片!"), bmpFileName );
}
else if( errCode == 8 )
{
DebugMB( _T("cGraphics::CreateFromBitmap:[%s]\nImageFile[%s]"), _T("内存不足!"), bmpFileName );
}
return FALSE;
}
HDC hdcBitmap; // memory DC
hdcBitmap = CreateCompatibleDC( NULL );
SelectObject( hdcBitmap, hBmp );
BITMAP bmp;
GetObject( hBmp, sizeof(BITMAP), &bmp );
DeleteObject( hBmp );
m_iWidth = bmp.bmWidth;
m_iHeight = bmp.bmHeight;
Release();
if( !Create( m_iWidth, m_iHeight ) )
{
DeleteDC( hdcBitmap );
return FALSE;
}
HRESULT hr;
HDC hdc;
hr = m_lpDDS->GetDC( &hdc );
if( hr == DD_OK )
{
StretchBlt( hdc,0, 0, m_iWidth, m_iHeight, hdcBitmap, 0, 0, m_iWidth, m_iHeight, SRCCOPY );
m_lpDDS->ReleaseDC( hdc );
}
else
{
DeleteDC( hdcBitmap );
return FALSE;
}
DeleteDC( hdcBitmap );
return TRUE;
}
BOOL cGraphics::SetClipper( LPDIRECTDRAWCLIPPER lpDDC, HWND hWnd )
{
g_pDirectDraw->GetDirectDraw()->CreateClipper( 0, &lpDDC, NULL );
lpDDC->SetHWnd( 0, hWnd );
HRESULT hr = m_lpDDS->SetClipper( lpDDC );
if( hr == DD_OK )
return TRUE;
return FALSE;
}
BOOL cGraphics::LoadBitmap( TCHAR* bmpFileName, int width, int height )
{
if( bmpFileName == NULL )
return FALSE;
HBITMAP hBmp;
hBmp = ( HBITMAP )LoadImage( GetModuleHandle(NULL), bmpFileName, IMAGE_BITMAP, width, height, LR_LOADFROMFILE );
if( hBmp == NULL )
{
int errCode = GetLastError();
if( errCode == 8 )
{
DebugMB( _T("cGraphics::LoadBitmap:[%s]"), _T("内存不足!") );
}
return FALSE;
}
if( !LoadBitmap( hBmp, 0, 0, 0, 0 ) )
return FALSE;
DeleteObject( hBmp );
return TRUE;
}
BOOL cGraphics::LoadBitmap( HBITMAP hBmp, int xSrc, int ySrc, int srcWidth, int srcHeight )
{
return LoadBitmap( hBmp, 0, 0, xSrc, ySrc, srcWidth, srcHeight );
}
BOOL cGraphics::LoadBitmap( HBITMAP hBmp, int left, int top, int xSrc, int ySrc, int srcWidth, int srcHeight )
{
//if( m_lpDDS == NULL || hBmp == NULL )
// return FALSE;
if( hBmp == NULL )
return FALSE;
//m_lpDDS->Restore();
m_lpDDS->Restore();
HDC hdcBitmap; // memory DC
hdcBitmap = CreateCompatibleDC( NULL );
SelectObject( hdcBitmap, hBmp );
BITMAP bmp;
GetObject( hBmp, sizeof(BITMAP), &bmp );
if( srcWidth == 0 )
srcWidth = bmp.bmWidth;
if( srcHeight == 0 )
srcHeight = bmp.bmHeight;
DDSURFACEDESC2 ddsd;
ddsd.dwSize = sizeof( DDSURFACEDESC2 );
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
//m_lpDDS->GetSurfaceDesc( &ddsd );
m_lpDDS->GetSurfaceDesc( &ddsd );
HDC hdc;
HRESULT hr;
//hr = m_lpDDS->GetDC( &hdc );
hr = m_lpDDS->GetDC( &hdc );
if( hr == DD_OK )
{
StretchBlt( hdc,0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcBitmap, xSrc, ySrc, srcWidth, srcHeight, SRCCOPY );
//m_lpDDS->ReleaseDC( hdc );
m_lpDDS->ReleaseDC( hdc );
}
else
return FALSE;
DeleteDC( hdcBitmap );
return TRUE;
}
BOOL cGraphics::LoadBitmap( TCHAR* bmpFileName, int xSrc, int ySrc, int srcWidth, int srcHeight )
{
return LoadBitmap( bmpFileName, 0, 0, xSrc, ySrc, srcWidth, srcHeight );
}
BOOL cGraphics::LoadBitmap( TCHAR* bmpFileName, int left, int top, int xSrc, int ySrc, int srcWidth, int srcHeight )
{
if( bmpFileName == NULL )
return FALSE;
HBITMAP hBmp;
hBmp = ( HBITMAP )LoadImage( GetModuleHandle(NULL), bmpFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
if( hBmp == NULL )
return FALSE;
if( !LoadBitmap( hBmp, left, top, xSrc, ySrc, srcWidth, srcHeight ) )
return FALSE;
DeleteObject( hBmp );
return TRUE;
}
BOOL cGraphics::SetColorKey( COLORREF rgb)
{
m_bColorKey = TRUE;
m_clrKey = rgb;
DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue = RGB2GDIColor(rgb);
ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
HRESULT hr;
//hr = m_lpDDS->SetColorKey( DDCKEY_SRCBLT, &ddck );
hr = m_lpDDS->SetColorKey( DDCKEY_SRCBLT, &ddck );
if( hr == DD_OK )
return TRUE;
return FALSE;
}
DWORD cGraphics::RGB2GDIColor( COLORREF clrGDIColor )
{
COLORREF rgbT;
HDC hdc;
DWORD dw = CLR_INVALID;
DDSURFACEDESC2 ddsd;
HRESULT hres;
//
// use GDI SetPixel to color match for us
//
//if (rgb != CLR_INVALID && m_lpDDS->GetDC(&hdc) == DD_OK)
if( clrGDIColor != CLR_INVALID && m_lpDDS->GetDC( &hdc ) == DD_OK )
{
rgbT = GetPixel(hdc, 0, 0); // save current pixel value
SetPixel(hdc, 0, 0, clrGDIColor); // set our value
//m_lpDDS->ReleaseDC(hdc);
m_lpDDS->ReleaseDC( hdc );
}
//
// now lock the surface so we can read back the converted color
//
ddsd.dwSize = sizeof(ddsd);
//while ((hres = m_lpDDS->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING);
while ((hres = m_lpDDS->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING);
if (hres == DD_OK)
{
dw = *(DWORD *)ddsd.lpSurface; // get DWORD
if(ddsd.ddpfPixelFormat.dwRGBBitCount < 32)
dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount)-1; // mask it to bpp
//m_lpDDS->Unlock(NULL);
m_lpDDS->Unlock( NULL );
}
//
// now put the color that was there back.
//
if (clrGDIColor != CLR_INVALID && m_lpDDS->GetDC(&hdc) == DD_OK)
{
SetPixel(hdc, 0, 0, rgbT);
m_lpDDS->ReleaseDC(hdc);
}
return dw;
}
BOOL cGraphics::ColorFill( COLORREF rgb )
{
//if( !m_lpDDS )
// return FALSE;
//if( !m_pSurface )
// return FALSE;
DDBLTFX ddBltFx;
ddBltFx.dwSize=sizeof(ddBltFx);
ddBltFx.dwFillColor=RGB2GDIColor(rgb);
if( DD_OK == m_lpDDS->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx) )
return TRUE;
return FALSE;
}
BOOL cGraphics::LoadGraphics( cGraphics* srcGraphics, LPRECT srcRect/* =NULL */)
{
return LoadGraphics( srcGraphics, 0, 0, srcRect );
}
BOOL cGraphics::LoadGraphics( cGraphics* srcGraphics, int left, int top, LPRECT srcRect )
{
if( !srcGraphics->GetSurface() )
return FALSE;
BOOL bAllocRect = FALSE;
if( srcRect == NULL )
{
bAllocRect = TRUE;
srcRect = new RECT;
srcRect->left = 0;
srcRect->top = 0;
srcRect->right = srcGraphics->m_iWidth;
srcRect->bottom = srcGraphics->m_iHeight;
}
//矩形裁剪
if( left >= m_iWidth || top >= m_iHeight )
return FALSE;
if( left < 0 )
{
srcRect->left -= left;
left = 0;
}
if( top < 0 )
{
srcRect->top -= top;
top = 0;
}
if( srcRect->left < 0 )
{
srcRect->right += srcRect->left;
srcRect->left = 0;
}
if( srcRect->top < 0 )
{
srcRect->bottom += srcRect->top;
srcRect->top = 0;
}
if( srcRect->right-srcRect->left+left - m_iWidth > 0 )
{
srcRect->right -= srcRect->right-srcRect->left+left - m_iWidth;
}
if( srcRect->bottom-srcRect->top+top - m_iHeight > 0 )
{
srcRect->bottom -= srcRect->bottom-srcRect->top+top - m_iHeight;
}
if( srcRect->left >= srcRect->right || srcRect->top >= srcRect->bottom )
return FALSE;
//贴图
HRESULT hr;
if( srcGraphics->m_bColorKey )
hr = m_lpDDS->BltFast( left, top, srcGraphics->GetSurface(), srcRect, DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY );
else
hr = m_lpDDS->BltFast( left, top, srcGraphics->GetSurface(), srcRect, DDBLTFAST_WAIT );
if( bAllocRect )
SAFE_DELETE( srcRect );
if( hr == DD_OK )
return TRUE;
return FALSE;
}
BOOL cGraphics::LoadGraphics( cGraphics* srcGraphics, int xSrc, int ySrc, int xWidth, int yHeight )
{
return LoadGraphics( srcGraphics, 0, 0, xSrc, ySrc, xWidth, yHeight );
}
BOOL cGraphics::LoadGraphics( cGraphics* srcGraphics, int left, int top, int xSrc, int ySrc, int xWidth, int yHeight )
{
RECT rcCut;
rcCut.left = xSrc;
rcCut.top = ySrc;
rcCut.right = xWidth+xSrc;
rcCut.bottom = yHeight+ySrc;
return LoadGraphics( srcGraphics, left, top, &rcCut );
}
BOOL cGraphics::DisplayText( TCHAR* text,int left,int top,COLORREF rgb/* =RGB(255 ,255,255)*/ )
{
HDC hDC;
m_lpDDS->GetDC( &hDC );
::SetBkMode( hDC, TRANSPARENT );
::SetTextColor( hDC, rgb );
if( !::TextOut( hDC, left, top, text, _tcslen(text) ) )
{
//m_lpDDS->ReleaseDC( hDC );
m_lpDDS->ReleaseDC( hDC );
return FALSE;
}
//m_lpDDS->ReleaseDC( hDC );
m_lpDDS->ReleaseDC( hDC );
return TRUE;
}
BOOL cGraphics::DisplayText( int left, int top, COLORREF rgb, TCHAR* chFormat, ... )
{
TCHAR text[256];
memset( text, 0, sizeof(TCHAR)*256 );
va_list args;
va_start( args, chFormat );
_vstprintf( text, chFormat, args );
DisplayText( text, left, top, rgb );
va_end( args );
return TRUE;
}
BOOL cGraphics::DisplayText( RECT* pRectText, COLORREF rgb, TCHAR* chFormat, ... )
{
HDC hDC;
m_lpDDS->GetDC( &hDC );
::SetBkMode( hDC, TRANSPARENT );
::SetTextColor( hDC, rgb );
LOGFONT lf;
memset( &lf, 0, sizeof(LOGFONT) );
_tcscpy( lf.lfFaceName, _T("宋体") );
lf.lfHeight = 12;
lf.lfWidth = 10;
SelectObject( hDC, CreateFontIndirect( &lf ) );
UINT uFormat = DT_SINGLELINE | DT_NOPREFIX | DT_TOP |DT_CENTER | DT_END_ELLIPSIS ;
TCHAR text[256];
memset( text, 0, sizeof(TCHAR)*256 );
va_list args;
va_start( args, chFormat );
_vstprintf( text, chFormat, args );
va_end( args );
::DrawText( hDC, text, _tcslen(text), pRectText, uFormat );
m_lpDDS->ReleaseDC( hDC );
return TRUE;
}
BOOL cGraphics::SaveToBMP( char* fileName )
{
DDSURFACEDESC2 ddsd;
memset( &ddsd, 0, sizeof(DDSURFACEDESC2) );
ddsd.dwSize = sizeof(DDSURFACEDESC2);
m_lpDDS->Lock( NULL, &ddsd, DDLOCK_WAIT, NULL );
BYTE* p = (BYTE*)ddsd.lpSurface;
// 打开文件
FILE* fp;
if( (fp=fopen(fileName, "wb")) != NULL )
{
// 保存文件头
BITMAPFILEHEADER FileHeader;
FileHeader.bfType = 'MB';// Not BM
FileHeader.bfSize = m_iWidth * m_iHeight * 3 + 0x36;
FileHeader.bfReserved1 = 0;
FileHeader.bfReserved2 = 0;
FileHeader.bfOffBits = 0x36;
fwrite(&FileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
// 保存文件信息
BITMAPINFOHEADER Header;
Header.biSize = sizeof(BITMAPINFOHEADER); // 结构的大小
Header.biWidth = m_iWidth; // 宽
Header.biHeight = m_iHeight; // 高
Header.biPlanes = 1; // 固定
Header.biBitCount = 24; // 颜色数
Header.biCompression = BI_RGB; // 是否压缩
Header.biSizeImage = m_iWidth * m_iHeight * 3; // 图片的大小
Header.biXPelsPerMeter = 0;
Header.biYPelsPerMeter = 0;
Header.biClrUsed = 0;
Header.biClrImportant = 0;
fwrite(&Header, Header.biSize, 1, fp);
// 写入具体内容(从下向上存放)
fseek(fp, 0x36, SEEK_SET);
if( ddsd.ddpfPixelFormat.dwRGBBitCount == 32 )
{
int iPitch = ((4-ddsd.dwWidth&3)&3);
p += (m_iHeight - 1) * ddsd.lPitch;
for(int i=0; i<m_iHeight; i++)
{
for(int j=0; j<m_iWidth; j++)
{
fputc( p[0], fp); // b
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -