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

📄 bmp.cpp

📁 DirectX 封装
💻 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 + -