?? mbmpclass.cpp
字號:
// MBmpClass.cpp: implementation of the MBmpClass class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "FPSystem.h"
#include "MBmpClass.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
MBmpClass::MBmpClass()
{
hImgData=NULL;
hBitmap=NULL;
hPalette=NULL;
}
MBmpClass::~MBmpClass()
{
if(hBitmap)
DeleteObject(hBitmap);
if(hPalette)
DeleteObject(hPalette);
if(hImgData!=NULL)
{
GlobalUnlock(hImgData);
GlobalFree(hImgData);
hImgData=NULL;
}
}
/****************************************************************
*
* 函數名稱:
* LoadBMPFile();
*
* 參數:
* char *inFileName 加載圖像的文件名
* CDC *pDC 設備上下文
* 返回值:
* TRUE 成功讀取;
* FALSE 失敗;
*
* 說明:
* 該函數讀入圖像文件文件數據到全局內存句柄hImgData中;
*
****************************************************************/
BOOL MBmpClass::LoadBmpFile(CString &inFileName,CDC *pDC) //070426加上了CDC *pDC
{
if(hImgData!=NULL)
{
GlobalUnlock(hImgData);
GlobalFree(hImgData);
hImgData=NULL;
}
CFile file; //文件對象
if(NULL==file.Open(inFileName,CFile::modeRead))
{
AfxMessageBox("文件打開有誤!",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
//讀入文件頭,并判斷是否為Bmp格式
file.Read((LPSTR)&bf,sizeof(BITMAPFILEHEADER));
if(bf.bfType!=0x4D42)
{
AfxMessageBox("File isn't a bmp file!");
file.Close();
return FALSE;
}
//讀入信息頭
file.Read((LPSTR)&bi,sizeof(BITMAPINFOHEADER));
//計算一行所需的字節數
DWORD LineBytes; //BMP圖像中一行所需的數據長度
LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
//計算整幅圖像數據所需的內存空間
DWORD ImgSize; //整幅圖像數據所需的內存空間
ImgSize=(DWORD)LineBytes*bi.biHeight;
//顏色數
DWORD NumColors; //用到的顏色數,if=0 then True color 24 bits
if(bi.biClrUsed!=0)//直接指定顏色數
{
NumColors=(DWORD)bi.biClrUsed;
}
else //根據圖像深度計算顏色數
{
switch(bi.biBitCount)
{
case 1:
NumColors=2; //二值圖像
bi.biClrUsed=2;
break;
case 4:
NumColors=16; //16色圖像
bi.biClrUsed=16;
break;
case 8:
NumColors=256; //256色圖像
bi.biClrUsed=256;
break;
case 24:
NumColors=0; //無調色板
break;
default:
AfxMessageBox("Invalid color numbers!",MB_OK|MB_ICONEXCLAMATION);
file.Close();
return FALSE;
}
}
//判斷圖像的偏移地址是否正確
if(bf.bfOffBits!=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)))
{
AfxMessageBox("Invalid color numbers!",MB_OK|MB_ICONEXCLAMATION);
file.Close();
return FALSE;
}
//計算整個文件的大小
bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;
//內存數據區hImgData=包括位圖信息頭+顏色表+圖象數據
if(hImgData!=NULL)
{
GlobalUnlock(hImgData);
GlobalFree(hImgData);
hImgData=NULL;
}
if((hImgData=GlobalAlloc(GHND,(DWORD)(sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize)))==NULL)
{
AfxMessageBox("Error alloc memory!",MB_OK|MB_ICONEXCLAMATION);
file.Close();
return FALSE;
}
////鎖定內存數據區,將圖像數據區內容讀入內存
LPBITMAPINFOHEADER lpImgData; //原始邏輯位圖信息頭
lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);
file.Seek(sizeof(BITMAPFILEHEADER),CFile::begin);
file.Read((void *)lpImgData,(DWORD)(bf.bfSize-sizeof(BITMAPFILEHEADER)));
file.Close();
/////////////////////設置調色板/////////////////
LOGPALETTE *pPal; //邏輯調色板指針
LPRGBQUAD lpRGB;
HPALETTE hPrevPalette; //前一個調色板句柄
HLOCAL hPal;
if(hBitmap)
{
DeleteObject(hBitmap);
hBitmap=NULL;
}
if(hPalette)
{
hPalette=NULL;
DeleteObject(hPalette);
}
if(NumColors) //NumColors不為零,說明用到了調色板
{
//為邏輯調色板分配局部內存,大小為邏輯調色板結構長度加NumColors個PALETTENTRY
hPal=LocalAlloc(LHND,sizeof(LOGPALETTE)+NumColors*sizeof(PALETTEENTRY));
pPal=(LOGPALETTE *)LocalLock(hPal); //指針pPal指向該內存區
//填寫邏輯調色板結構的頭
pPal->palNumEntries=(WORD)NumColors;
pPal->palVersion=0x300; //為什么是0x300?
//lpRGB指向的是調色板開始的位置
lpRGB=(LPRGBQUAD)((LPSTR)lpImgData+(DWORD)sizeof(BITMAPINFOHEADER));
//填寫每一項
for(DWORD i=0;i<NumColors;i++)
{
pPal->palPalEntry[i].peRed=lpRGB->rgbRed;
pPal->palPalEntry[i].peGreen=lpRGB->rgbGreen;
pPal->palPalEntry[i].peBlue=lpRGB->rgbBlue;
pPal->palPalEntry[i].peFlags=(BYTE) 0;
lpRGB++;
}
hPalette=CreatePalette(pPal); //調色板產生
LocalUnlock(hPal);
LocalFree(hPal); //釋放邏輯調色板空間
}
if(hPalette)
{
hPrevPalette=SelectPalette(pDC->m_hDC,hPalette,FALSE);
RealizePalette(pDC->m_hDC); //將現有邏輯調色板影射到系統調色板
}
hBitmap=CreateDIBitmap(pDC->m_hDC,(LPBITMAPINFOHEADER)lpImgData,(DWORD)CBM_INIT,
(LPSTR)lpImgData+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD),
(LPBITMAPINFO)lpImgData,DIB_RGB_COLORS);
if(hPalette && hPrevPalette)
{
SelectPalette(pDC->m_hDC,hPrevPalette,FALSE);
RealizePalette(pDC->m_hDC); //將現有邏輯調色板影射到系統調色板
}
GlobalUnlock(hImgData); //解鎖內存數據區
return TRUE;
}
/****************************************************************
*
* 函數名稱:
* SaveBmpFile();
*
* 參數:
* char *inFileName 加載圖像的文件名
* 返回值:
* TRUE 成功讀取;
* FALSE 失敗;
*
* 說明:
* 該函數讀入圖像文件文件數據到全局內存句柄hImgData中;
*
****************************************************************/
BOOL MBmpClass::SaveBmpFile(CString fileName)
{
CFile file;
if(!(file.Open(fileName,CFile::modeCreate|CFile::modeWrite)))
{
AfxMessageBox("文件打開失敗!",MB_OK|MB_ICONINFORMATION);
return FALSE;
}
LPBITMAPINFOHEADER lpImgDatan; //邏輯位圖信息頭
lpImgDatan=(LPBITMAPINFOHEADER)GlobalLock(hImgData);
//寫文件頭
file.Write((char*)&bf,sizeof(bf));
//寫信息頭 調色板 數據區
file.Write( (char*)lpImgDatan,bf.bfSize-sizeof(BITMAPFILEHEADER));
file.Flush(); //將輸出緩沖區的數據送出,并清出。
file.Close();
GlobalUnlock(hImgData); //解鎖hImgData
return TRUE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -