?? bmpproc.cpp
字號:
CBitmap cBmp;
HBITMAP hBmp;
int iCurDevBitPix, iCurDevPlanes;
// 獲取當前系統顯示器的顏色格式(位數和平面數)
HWND hWnd = ::GetDesktopWindow();
ASSERT(hWnd);
HDC hDC = ::GetDC(hWnd);
iCurDevBitPix = GetDeviceCaps(hDC,BITSPIXEL);
iCurDevPlanes = GetDeviceCaps(hDC,PLANES);
::ReleaseDC(hWnd, hDC);
// 創建指定尺寸并兼容當前顯示器顏色格式的位圖(DDB)
if (!cBmp.CreateBitmap(width, height, iCurDevPlanes, iCurDevBitPix, lpBits))
return FALSE;
hBmp = (HBITMAP)cBmp.Detach();
ASSERT(hBmp);
if (!hBmp)
return FALSE;
// 創建臨時位圖信息塊(不帶顏色表)
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)CreateMemoryBlockFromAddress(
(LPVOID)NULL, sizeof(BITMAPINFOHEADER));
if (!lpbi)
{
::DeleteObject(hBmp);
return FALSE;
}
// 設置DIB信息塊內容
lpbi->biSize = sizeof(BITMAPINFOHEADER);
lpbi->biWidth = width;
lpbi->biHeight = height;
lpbi->biPlanes = 1;
lpbi->biBitCount = nBitCount;
if ((nBitCount==16)||(nBitCount==32))
lpbi->biCompression = BI_BITFIELDS;
else
lpbi->biCompression = BI_RGB;
// 計算設備分辯率
hDC = ::GetDC(hWnd);
lpbi->biXPelsPerMeter = \
(GetDeviceCaps(hDC,HORZRES)*1000)/GetDeviceCaps(hDC,HORZSIZE);
lpbi->biYPelsPerMeter = \
(GetDeviceCaps(hDC,VERTRES)*1000)/GetDeviceCaps(hDC,VERTSIZE);
::ReleaseDC(hWnd, hDC);
lpbi->biClrUsed = 0;
lpbi->biClrImportant = 0;
lpbi->biSizeImage = CalculateDIBitsSize(lpbi);
// 計算顏色表的尺寸
WORD wPalSize = PaletteSize(lpbi);
// 創建帶顏色表的信息塊,并復制lpbi信息塊中的內容
LPBITMAPINFO pInfo = (LPBITMAPINFO)CreateMemoryBlockFromAddress(
(LPVOID)lpbi, sizeof(BITMAPINFOHEADER)+wPalSize);
if (!pInfo)
{
::free((void*)lpbi);
::DeleteObject(hBmp);
return FALSE;
}
ASSERT(pInfo->bmiHeader.biSize == sizeof(BITMAPINFOHEADER));
// 此時該結構已經無用,釋放
::free((void*)lpbi);
// 創建存放DIB位數據的緩沖區
LPSTR pBits = (LPSTR)CreateMemoryBlockFromAddress((LPVOID)NULL,
pInfo->bmiHeader.biSizeImage);
if (!pBits)
{
::free((void*)pInfo);
::DeleteObject(hBmp);
return FALSE;
}
// 下面的代碼并不是要獲取位圖的DIB位數據,而是要取得位圖的顏色表
// 顏色表數據在函數(GetDIBits())調用成功后被填寫在pInfo結構中
hDC = ::GetDC(hWnd);
if (!::GetDIBits(hDC,hBmp,0,height,(LPVOID)pBits,pInfo,DIB_RGB_COLORS))
{
::free((void*)pBits);
::free((void*)pInfo);
::ReleaseDC(hWnd, hDC);
::DeleteObject(hBmp);
return FALSE;
}
::ReleaseDC(hWnd, hDC);
// 此時并不需要DIB位數據,釋放
::free((void*)pBits);
// 刪除原來的圖像,并且設置新的位圖
if (!ClearAndSetData(IT_CREATE,0,(LPCTSTR)"",pInfo,hBmp))
{
::free((void*)pInfo);
::DeleteObject(hBmp);
return FALSE;
}
return TRUE;
}
/*************************************************************************
*
* CreateCompatible()
*
* 參數說明:
*
* int width - 創建位圖的寬度
* int height - 創建位圖的高度
* CDC *pDC, - 設備描述表(可以是NULL)
* const void *lpBits - 新位圖的初始化位數據(可以是NULL)
*
* 返回值:
*
* BOOL - 如果成功返回TRUE,否則返回FALSE
*
* 描述:
*
* 根據指定的數據創建一個顏色格式兼容于指定描述表的位圖,并貼入本身類中
*
* 注:
*
* # 入口參數width和height不能是0,如果指定了0,函數返回FALSE
* # 入口參數pDC可以是NULL,這時函數將按當前顯示器的顏色格式創建位圖,如果
* pDC不是NULL,則它必須指向一個有效的設備描述表
* # 如果本身類中原來存在圖像,則調用函數成功之后,原來的圖像將被刪除
* # 如果入口參數lpBits是NULL,則新創建的位不被初始化
*
************************************************************************/
BOOL CBmpProc::CreateCompatible(int width,
int height,
CDC *pDC,
const void *lpBits)
{
// 檢測寬度和高度值
if ((width==0)||(height==0))
return FALSE;
int iCurDevBitPix, iCurDevPlanes;
// 獲取當前系統顯示器的顏色格式(位數和平面數)
HWND hWnd = ::GetDesktopWindow();
ASSERT(hWnd);
if (pDC == NULL)
{
// 如果沒有指定設備描述表,則使用當前顯示器的顏色格式
HDC hDC = ::GetDC(hWnd);
iCurDevBitPix = GetDeviceCaps(hDC,BITSPIXEL);
iCurDevPlanes = GetDeviceCaps(hDC,PLANES);
::ReleaseDC(hWnd, hDC);
}
else
{
iCurDevBitPix = GetDeviceCaps(pDC->GetSafeHdc(),BITSPIXEL);
iCurDevPlanes = GetDeviceCaps(pDC->GetSafeHdc(),PLANES);
}
// 在16色的系統中,每像素的位數是1,而平面是4,將其顛倒后容易處理
if ((iCurDevPlanes!=1)&&(iCurDevBitPix==1))
{
iCurDevBitPix = iCurDevPlanes;
iCurDevPlanes = 1;
}
// 創建位圖(DDB)
return Create(width, height, iCurDevBitPix, lpBits);
}
/*************************************************************************
*
* CopyFromObject()
*
* 參數說明:
*
* CBmpProc& souBmp - 源位圖目標
* CRect *pDesRect - 目標矩形
* CRect *pSouRect - 源矩形
*
* 返回值:
*
* BOOL - 如果成功返回TRUE,否則返回FALSE
*
* 描述:
*
* 復制源位圖目標中指定區域(矩形)的圖像到本身類中圖像的指定區域
*
* 如果入口參數pDesRect設為NULL,則目標矩形等于源圖像的尺寸
* 如果入口參數pSouRect設為NULL,則源目標矩形等于源圖像的尺寸
* 如果入口參數pDesRect和pSouRect不同,該函數可能會產生拉伸或壓縮動作
*
* 注:# 本身類中原來必需已存在位圖,且調用之后的位圖不會被刪除
* # 如果源位圖類是空的,則返回FALSE
* # 如果本身類中沒有位圖,則函數返回FALSE
*
************************************************************************/
BOOL CBmpProc::CopyFromObject(CBmpProc& souBmp, CRect *pDesRect, CRect *pSouRect)
{
if (!IsValid())
return FALSE;
ASSERT(m_pInfo);
ASSERT(m_pInfo->bmiHeader.biSize == sizeof(BITMAPINFOHEADER));
if (!souBmp.IsValid())
return FALSE;
ASSERT(souBmp.m_pInfo);
ASSERT(souBmp.m_pInfo->bmiHeader.biSize == sizeof(BITMAPINFOHEADER));
// 如果未指定矩形數據,則使用源圖的矩形數據
CRect dr;
CRect sr;
if (pDesRect == NULL)
dr = souBmp.Rect();
else
dr = *pDesRect;
if (pSouRect == NULL)
sr = souBmp.Rect();
else
sr = *pSouRect;
// 復制源圖
CDC compDC, compDC2;
CBitmap *pOldBmp, *pOldBmp2;
// 創建與當前顯示設備兼容的內存設備描述表
compDC.CreateCompatibleDC(NULL);
compDC2.CreateCompatibleDC(NULL);
pOldBmp = compDC.SelectObject((CBitmap*)this);
pOldBmp2= compDC2.SelectObject((CBitmap*)&souBmp);
// 設置目標DC的拉伸模式為COLORONCOLOR,也就是不顯示拉伸掉的圖像
compDC.SetStretchBltMode(COLORONCOLOR);
// 復制指定尺寸的源位圖到目標位圖
compDC.StretchBlt(dr.left, dr.top, dr.Width(), dr.Height(),
&compDC2, sr.left, sr.top, sr.Width(), sr.Height(), SRCCOPY);
compDC2.SelectObject(pOldBmp2);
compDC.SelectObject(pOldBmp);
return TRUE;
}
/*************************************************************************
*
* CopyFromHbmp()
*
* 參數說明:
*
* HBITMAP souBmp - 源位圖句柄
* CRect *pDesRect - 目標矩形
* CRect *pSouRect - 源矩形
*
* 返回值:
*
* BOOL - 如果成功返回TRUE,否則返回FALSE
*
* 描述:
*
* 復制源位圖中指定區域(矩形)的圖像到本身類中圖像的指定區域
*
* 如果入口參數pDesRect設為NULL,則目標矩形等于源圖像的尺寸
* 如果入口參數pSouRect設為NULL,則源目標矩形等于源圖像的尺寸
* 如果入口參數pDesRect和pSouRect不同,該函數可能會產生拉伸或壓縮動作
*
* 注:# 本身類中原來必需已存在位圖,且調用之后的位圖不會被刪除
* # 如果源位圖類是空的,則返回FALSE
* # 如果本身類中沒有位圖,則函數返回FALSE
*
************************************************************************/
BOOL CBmpProc::CopyFromHbmp(HBITMAP souBmp,
CRect *pDesRect,
CRect *pSouRect)
{
// 檢查入口參數
if (!souBmp)
return FALSE;
// 檢查本類中是否有圖像
if (!IsValid())
return FALSE;
ASSERT(m_pInfo);
ASSERT(m_pInfo->bmiHeader.biSize == sizeof(BITMAPINFOHEADER));
CBmpProc tmp;
// 將句柄貼入臨時類中
if (!tmp.Attach(souBmp))
return FALSE;
BOOL ret = CopyFromObject(tmp, pDesRect, pSouRect);
tmp.Detach();
return ret;
}
/*************************************************************************
*
* CopyTran()
*
* 參數說明:
*
* CBmpProc& souBmp - 源位圖目標
* COLORREF crColour - 要濾掉或保留的顏色(缺省值是白色)
* int x - 目標矩形左上角X坐標(缺省值為0)
* int y - 目標矩形左上角Y坐標(缺省值為0)
* CRect *pSouRect - 源矩形(缺省值為NULL)
* int mode - 如果是0則將不拷貝指定的顏色,如果是1則保留指定
* 的顏色(缺省值為0)
*
* 返回值:
*
* BOOL - 如果成功返回TRUE,否則返回FALSE
*
* 描述:
*
* 透明的復制源位圖目標中指定矩形的圖像到本身類中圖像的指定區域
*
* 如果入口參數pSouRect設為NULL,則源目標矩形等于源圖像的尺寸。這樣該
* 函數將不產生拉伸或壓縮動作。
* 如果入口參數pSouRect不設為NULL,該函數會產生拉伸或壓縮動作
*
* 注:# 本身類中原來必需已存在位圖,且調用之后的位圖不會被刪除
* # 如果源位圖類是空的,則返回FALSE
* # 如果本身類中不存在位圖,函數將返回FALSE
*
************************************************************************/
BOOL CBmpProc::CopyTran(CBmpProc& souBmp,
COLORREF crColour,
int x, int y,
CRect *pSouRect,
int mode)
{
if (!IsValid())
return FALSE;
ASSERT(m_pInfo);
ASSERT(m_pInfo->bmiHeader.biSize == sizeof(BITMAPINFOHEADER));
if (!souBmp.IsValid())
return FALSE;
ASSERT(souBmp.m_pInfo);
ASSERT(souBmp.m_pInfo->bmiHeader.biSize == sizeof(BITMAPINFOHEADER));
CRect dr(souBmp.Rect());
dr.OffsetRect(x, y);
return CopyTran(souBmp, crColour, &dr, pSouRect, mode);
}
/*************************************************************************
*
* CopyTran()
*
* 參數說明:
*
* CBmpProc& souBmp - 源位圖目標
* COLORREF crColour - 要濾掉或保留的顏色(缺省值是白色)
* CRect *pDesRect - 目標矩形(缺省值為NULL)
* CRect *pSouRect - 源矩形(缺省值為NULL)
* int mode - 如果是0則將不拷貝指定的顏色,如果是1則保留指定
* 的顏色(缺省值為0)
*
* 返回值:
*
* BOOL - 如果成功返回TRUE,否則返回FALSE
*
* 描述:
*
* 透明的復制源位圖目標中指定矩形的圖像到本身類中圖像的指定區域
*
* 如果入口參數pDesRect設為NULL,則目標矩形等于源圖像的尺寸。
* 如果入口參數pSouRect設為NULL,則源目標矩形等于源圖像的尺寸。
* 如果pDesRect和pSouRect相同,則該函數將不會產生拉伸或壓縮動作。
*
* 注:# 本身類中原來必需已存在位圖,且調用之后的位圖不會被刪除
* # 如果源位圖類是空的,則返回FALSE
* # 如果本身類中不存在位圖,函數將返回FALSE
*
************************************************************************/
BOOL CBmpProc::CopyTran(CBmpProc& souBmp,
COLORREF crColour,
CRect *pDesRect,
CRect *pSouRect,
int mode)
{
if (!IsValid())
return FALSE;
ASSERT(m_pInfo);
ASSERT(m_pInfo->bmiHeader.biSize == sizeof(BITMAPINFOHEADER));
if (!souBmp.IsValid())
return FALSE;
ASSERT(souBmp.m_pInfo);
ASSERT(souBmp.m_pInfo->bmiHeader.biSize == sizeof(BITMAPINFOHEADER));
// 如果未指定矩形數據,則使用源圖的矩形數據
CRect dr;
CRect sr;
if (pDesRect == NULL)
dr = souBmp.Rect();
else
dr = *pDesRect;
if (pSouRect == NULL)
sr = souBmp.Rect();
else
sr = *pSouRect;
// 復制源圖
CDC compDC;
CBitmap *pOldBmp;
// 創建與當前顯示設備兼容的內存設備描述表
compDC.CreateCompatibleDC(NULL);
pOldBmp = compDC.SelectObject((CBitmap*)this);
// 復制指定尺寸的源位圖到目標位圖
souBmp.DrawTransparentInRect(compDC, crColour, pDesRect, pSouRect, mode);
compDC.SelectObject(pOldBmp);
return TRUE;
}
/*************************************************************************
*
* CopyTranCenter()
*
* 參數說明:
*
* CBmpProc& souBmp - 源位圖目標
* CRect* crArea - 居中的范圍(缺省值為NULL)
* COLORREF crColour - 要濾掉或保留的顏色(缺省值是白色)
* int mode - 如果是0則將不拷貝指定的顏色,如果是1則保留指定
* 的顏色(缺省值為0)
*
* 返回值:
*
* BOOL - 如果成功返回TRUE,否則返回FALSE
*
* 描述:
*
* 將源位圖透明的復制到本類中指定矩形的中央
*
* 如果入口參數crArea設為NULL,則居中矩形等于本身類中圖像的尺寸。
* 該函數不會產生拉伸或壓縮動作。
*
* 注:# 本身類中原來必需已存在位圖,且調用之后的位圖不會被刪除
* # 如果源位圖類是空的,則返回FALSE
* # 如果本身類中不存在位圖,函數將返回FALSE
*
************************************************************************/
BOOL CBmpProc::CopyTranCenter(CBmpProc& souBmp,
CRect* crArea,
COLORREF crColour,
int mode)
{
if (!IsValid())
return FALSE;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -