📄 bmp.cpp
字号:
// BMP.cpp: implementation of the BMP class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Win32.h"
#include "BMP.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
BMP::BMP()
{
}
BMP::~BMP()
{
if(BMP::hdc!=NULL)
{
DeleteObject(hdc);
}
if(BMP::pDib!=NULL)
{
GlobalFree(pDib);
}
if(BMP::lpDDSBmp!=NULL)
{
DWORD test=lpDDSBmp->Release();
lpDDSBmp=NULL;
}
}
BMP::BMP(char* FileName)
{
BMP::lpDDSBmp=NULL;
strcpy(m_FileName,FileName);
BMP::LoadFile();
BMP::DIBToDDB();
}
UINT BMP::GetNumberOfColor()
{
UINT nColors=m_pBitmapinfoHeader->biClrUsed ? m_pBitmapinfoHeader->biClrUsed :
1<<m_pBitmapinfoHeader->biBitCount;
return nColors;
}
void BMP::LoadFile()
{
HANDLE hBmpFile;
BITMAPFILEHEADER bitmapFileHeader;
hBmpFile=(HANDLE)CreateFile(m_FileName,GENERIC_READ,FILE_SHARE_READ,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
//SetFilePointer(hBmpFile,0,NULL,FILE_BEGIN);
DWORD dwFileRead;
//LPDWORD lpFileSizeHigh;
//dwFileRead=sizeof(BITMAPFILEHEADER);
BOOL b=ReadFile(hBmpFile,&bitmapFileHeader,sizeof(BITMAPFILEHEADER),&dwFileRead,NULL);
if(bitmapFileHeader.bfType==0x4d42)//必须是位图
{
//DWORD FileSizeHigh;
DWORD FileLength=GetFileSize(hBmpFile,NULL);
DWORD size=FileLength-sizeof(BITMAPFILEHEADER);
BYTE* pDib=(BYTE* )GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,size);
//dwFileRead=size;
b=ReadFile(hBmpFile,(void* )pDib,size,&dwFileRead,NULL);
if(dwFileRead!=size)
return;
b=CloseHandle(hBmpFile);
BMP::m_pBitmapInfo=(BITMAPINFO* )pDib;
BMP::m_pBitmapinfoHeader=(BITMAPINFOHEADER* )pDib;
m_pRGB=(RGBQUAD* )(pDib+BMP::m_pBitmapinfoHeader->biSize);
int m_numberOfColor=BMP::GetNumberOfColor();
if(BMP::m_pBitmapinfoHeader->biClrUsed==0)
{
BMP::m_pBitmapinfoHeader->biClrUsed=m_numberOfColor;
}
DWORD colorTableSize=m_numberOfColor*sizeof(RGBQUAD);
//DWORD kk=sizeof(BITMAPINFOHEADER);
if(m_numberOfColor<=256)
BMP::m_pData=pDib+BMP::m_pBitmapinfoHeader->biSize+colorTableSize;
else
BMP::m_pData=pDib+BMP::m_pBitmapinfoHeader->biSize;//+colorTableSize;
BMP::m_pBitmapinfoHeader->biSizeImage=GetSize();
BMP::m_valid=TRUE;
//GlobalFree(pDib);
}
else
{
BMP::m_valid=FALSE;
CloseHandle(hBmpFile);
}
}
DWORD BMP::GetSize()
{
if(BMP::m_pBitmapinfoHeader->biSizeImage!=0)
{
return BMP::m_pBitmapinfoHeader->biSizeImage;
}
else
{
DWORD height=(DWORD)GetHeight();
DWORD width=(DWORD)GetWidth();
return(height*width);
}
}
DWORD BMP::GetWidth()
{
return((UINT)BMP::m_pBitmapinfoHeader->biWidth);
}
DWORD BMP::GetHeight()
{
return((UINT)BMP::m_pBitmapinfoHeader->biHeight);
}
BITMAPINFO* BMP::GetInfo()
{
return(BMP::m_pBitmapInfo);
}
BYTE* BMP::GetData()
{
return(BMP::m_pData);
}
RGBQUAD* BMP::GetRGB()
{
return(BMP::m_pRGB);
}
BOOL BMP::IsValid()
{
return (BMP::m_valid);
}
BOOL BMP::DrawToGDI(HDC Desthdc,RECT ObjRect,RECT ResRect,DWORD state)
{
BOOL GdiRet=StretchBlt(Desthdc,ObjRect.left,ObjRect.top,ObjRect.right-ObjRect.left,ObjRect.bottom-ObjRect.top,
hdc,ResRect.left,ResRect.top,ResRect.right-ResRect.left,ResRect.bottom-ResRect.top,
state);
/*int GdiRet=StretchDIBits(GDIhdc,ObjRect.left,ObjRect.top,ObjRect.right-ObjRect.left,ObjRect.bottom-ObjRect.top,
ResRect.left,ResRect.top,ResRect.right-ResRect.left,ResRect.bottom-ResRect.top,
m_pData,m_pBitmapInfo,DIB_RGB_COLORS,SRCCOPY);*/
if(GdiRet!=FALSE)
{
//ReleaseDC(hWnd,GDIhdc);
return TRUE;
}
else
{
return FALSE;
}
}
void BMP::SetTransparentColor(COLORREF RGBvalue)
{
BMP::TransparentColor=RGBvalue;
}
BOOL BMP::DrawSpirit(HDC hdcDest,RECT rDest,RECT rSrce)
{
BOOL ret=TransparentBlt(hdcDest,rDest.left,rDest.top,rDest.right-rDest.left,rDest.bottom-rDest.top,
hdc,rSrce.left,rSrce.top,rSrce.right-rSrce.left,rSrce.bottom-rSrce.top,
TransparentColor);
return ret;
}
BOOL BMP::LoadBmpTohdc(HDC hdc)
{
DWORD nHeight=BMP::GetHeight();
DWORD nWidth=BMP::GetWidth();
//hdc=CreateDC("DISPLAY",NULL,NULL,NULL);
//hdc=GetDC(hHideWnd);
int GdiRet=StretchDIBits(hdc,0,0,nWidth,nHeight,
0,0,nWidth,nHeight,
m_pData,m_pBitmapInfo,DIB_RGB_COLORS,SRCCOPY);
if(GdiRet!=GDI_ERROR)
{
return TRUE;
}
else
{
return FALSE;
}
}
HBITMAP BMP::DIBToDDB()
{
HPALETTE hPal;
//LPRGBQUAD pRGBTable=BMP::GetRGB();
int ColorNumber=GetNumberOfColor();
int nSize=sizeof(LOGPALETTE)+ColorNumber*sizeof(RGBQUAD);
LOGPALETTE *plogpalette=(LOGPALETTE *)new BYTE[nSize];
plogpalette->palVersion=0x300;
plogpalette->palNumEntries=ColorNumber;
LPBITMAPINFO lpbi=(LPBITMAPINFO)GetInfo();
if(ColorNumber<=256)
{
for(UINT n=0;n<ColorNumber;n++)
{
plogpalette->palPalEntry[n].peBlue=lpbi->bmiColors[n].rgbBlue;
plogpalette->palPalEntry[n].peGreen=lpbi->bmiColors[n].rgbGreen;
plogpalette->palPalEntry[n].peRed=lpbi->bmiColors[n].rgbRed;
plogpalette->palPalEntry[n].peFlags=0;
}
hPal=CreatePalette(plogpalette);
delete plogpalette;
}
HBITMAP hBitmap=NULL; // 设备相关位图对象
HDC hTmpDC;
hTmpDC=GetDC(NULL);
HPALETTE hOld=SelectPalette(hTmpDC,hPal,FALSE);
RealizePalette(hTmpDC);
hBitmap=CreateDIBitmap(hTmpDC,m_pBitmapinfoHeader,CBM_INIT,m_pData,m_pBitmapInfo,DIB_RGB_COLORS);
hdc=CreateCompatibleDC(0);
HGDIOBJ ret=SelectObject(BMP::hdc,hBitmap);
SelectPalette(hTmpDC,hOld,FALSE);
ReleaseDC(NULL,hTmpDC);
return hBitmap;
}
BOOL BMP::LoadBmpTpDDSurface(LPDIRECTDRAW lpDD)
{
DDSURFACEDESC ddsd;
//HRESULT ddrval;
HDC DC;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN |DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = BMP::GetWidth();
ddsd.dwHeight = BMP::GetHeight();
int Width=GetWidth();
int Height=GetHeight();
if(lpDD->CreateSurface(&ddsd, &lpDDSBmp, NULL) != DD_OK)
return FALSE;
lpDDSBmp->Restore();
lpDDSBmp->GetDC(&DC);
BOOL ret=StretchBlt(DC,0,0,Width,Height,BMP::hdc,0,0,Width,Height,SRCCOPY);
//BOOL ret=TransparentBlt(DC,0,0,Width,Height,hdc,0,0,Width,Height,TransparentColor);
lpDDSBmp->ReleaseDC(DC);
return ret;
//return BMP::lpDDSBmp;
}
LPDIRECTDRAWSURFACE BMP::GetSurface()
{
return BMP::lpDDSBmp;
}
BOOL BMP::BltToDDSurface(LPDIRECTDRAWSURFACE lpDestSurface,LPRECT DestRect,LPRECT SurRect)
{
if(((SurRect->left)>=0)&&((SurRect->top)>=0)&&((SurRect->right)<=GetWidth())&&((SurRect->bottom)<=GetHeight()))
{
HRESULT ddrval=lpDestSurface->Blt(DestRect,lpDDSBmp,SurRect,DDBLT_WAIT|DDBLT_KEYSRC, NULL);
if(ddrval!=DD_OK)
{
OutPutError(ddrval);
return FALSE;
}
else
{
return TRUE;
}
}
else
{
MessageBox(NULL,"源矩形区域错误","错误",MB_OK);
PostQuitMessage(0);
}
return TRUE;
}
DWORD BMP::DDColorMatch(IDirectDrawSurface *pdds, COLORREF rgb)
{
COLORREF rgbT;
HDC hdc;
DWORD dw = CLR_INVALID;
DDSURFACEDESC ddsd;
HRESULT hres;
//
// use GDI SetPixel to color match for us
//
if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
{
rgbT = GetPixel(hdc, 0, 0); // save current pixel value
SetPixel(hdc, 0, 0, rgb); // set our value
pdds->ReleaseDC(hdc);
}
//
// now lock the surface so we can read back the converted color
//
ddsd.dwSize = sizeof(ddsd);
while ((hres = pdds->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
;
if (hres == DD_OK)
{
dw = *(DWORD *)ddsd.lpSurface; // get DWORD
dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount)-1; // mask it to bpp
pdds->Unlock(NULL);
}
//
// now put the color that was there back.
//
if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
{
SetPixel(hdc, 0, 0, rgbT);
pdds->ReleaseDC(hdc);
}
return dw;
}
HRESULT BMP::SetDDSurColorKey(COLORREF rgb)
{
DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue = DDColorMatch(BMP::lpDDSBmp, rgb);
ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
HRESULT ddrval=BMP::lpDDSBmp->SetColorKey(DDCKEY_SRCBLT, &ddck);
//HRESULT ddrval=DDSetColorKey(lpDDSBmp,RGB(0,0,0));
return ddrval;
}
HDC BMP::GetGDIDC()
{
return BMP::hdc;
}
void BMP::SetGDIDC(HDC newDC)
{
BMP::hdc=newDC;
}
void BMP::SetSurface(LPDIRECTDRAWSURFACE newSurface)
{
BMP::lpDDSBmp=newSurface;
}
COLORREF BMP::GetBMPPixel(int x,int y)
{
LPBYTE pBmp_Data=GetData();
return((COLORREF)(*(pBmp_Data+y*(GetWidth()>>1)+x)));
}
BOOL BMP::SetBmpPixel(int x, int y,COLORREF nColor)
{
LPBYTE pBmp_Data=GetData();
*(pBmp_Data+y*(GetWidth()>>1)+x)=nColor;
return(SetData(pBmp_Data));
}
BOOL BMP::SetData(LPBYTE pData)
{
if(pData)
{
BMP::m_pData=pData;
return TRUE;
}
else
{
return FALSE;
}
}
struct BufferSurfaceAddress BMP::BeginBmpWriteSuface()
{
DDSURFACEDESC ddsd;
HRESULT ddrval;
//LPWORD lpSurface;
long Pitch;
BufferSurfaceAddress BufferAddress;
ddsd.dwSize = sizeof(ddsd);
// 锁定Back Surface,DDraw中的Surface必须先锁定,然后才能访问
while((ddrval=lpDDSBmp->Lock(NULL, &ddsd, 0, NULL))==DDERR_WASSTILLDRAWING);
if(ddrval == DD_OK)
{
BufferAddress.lpSurface = (LPWORD)ddsd.lpSurface;
// 我们关心的Pitch,其值是字节(BYTE)数
Pitch = ddsd.lPitch;
Pitch >>= 1; // 为了方便后面的计算,把它换算成字(WORD)数
BufferAddress.Pitch=Pitch;
}
//lpDDSBack->Unlock(NULL);
return BufferAddress;
}
void BMP::EndBmpWriteSurface()
{
lpDDSBmp->Unlock(NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -