?? dib.cpp
字號:
// ************************************************************************
// 文件名:dib.cpp
//
// DIB(Independent Bitmap) 函數庫:
//
// PaintDIB() - 繪制DIB對象
// CreateDIBPalette() - 創建DIB對象調色板
// FindDIBBits() - 返回DIB圖像象素起始位置
// DIBWidth() - 返回DIB寬度
// DIBHeight() - 返回DIB高度
// PaletteSize() - 返回DIB調色板大小
// DIBNumColors() - 計算DIB調色板顏色數目
// CopyHandle() - 拷貝內存塊
// DIBBitCount() - 該函數返回DIBBitCount
// SaveDIB() - 將DIB保存到指定文件中
// ReadDIBFile() - 重指定文件中讀取DIB對象
// SetRgnColor() - 用指定的顏色填充指定的區域
// SetCircleColor() - 用指定的顏色填充指定的圓形區域
//
// ************************************************************************
#include "stdafx.h"
#include "dib.h"
#include <io.h>
#include <errno.h>
#include <math.h>
#include <direct.h>
// Dib文件頭標志(字符串"BM",寫DIB時用到該常數)
#define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B')
CDIB::CDIB()
{
}
CDIB::~CDIB()
{
}
////////////////////////////////////////////////////////////////////////////
// 功能模塊開始 //
////////////////////////////////////////////////////////////////////////////
/*************************************************************************
*
* 函數名稱:
* PaintDIB()
*
* 參數:
* HDC hDC - 設備環境句柄
* LPRECT lpDCRect - 矩形區域
* HDIB hDIB - 指向DIB對象的指針
* LPRECT lpDIBRect - 待輸出DIB區域
* CPalette* pPal - 調色板指針
*
* 返回值:
* BOOL - 繪制成功返回TRUE,否則返回FALSE。
*
* 說明:
* 繪制DIB對象
*
************************************************************************/
BOOL CDIB::PaintDIB(HDC hDC,
LPRECT lpDCRect,
HDIB hDIB,
LPRECT lpDIBRect,
CPalette* pPal)
{
LPBYTE lpDIBINFOHEADER; // BITMAPINFOHEADER指針
LPBYTE lpDIBBits; // DIB象素指針
BOOL bRet = FALSE; // 返回成功標志
HPALETTE hNewPal = NULL; // 當前的調色板
HPALETTE hOldPal = NULL; // 以前的調色板
// 判斷DIB對象是否為空
if (hDIB == NULL)
{
// 返回
return FALSE;
}
// 鎖定DIB
lpDIBINFOHEADER = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB圖像象素起始位置
lpDIBBits = FindDIBBits(lpDIBINFOHEADER);
// 獲取DIB調色板,并選中
if (pPal != NULL)
{
hNewPal = (HPALETTE) pPal->m_hObject;
// 選中調色板
hOldPal = ::SelectPalette(hDC, hNewPal, TRUE);
}
// 設置顯示模式
::SetStretchBltMode(hDC, COLORONCOLOR);
// 判斷是調用StretchDIBits()還是SetDIBitsToDevice()來繪制DIB對象
if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) &&
(RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))
{
// 原始大小,不用拉伸。
bRet = ::SetDIBitsToDevice(hDC, // hDC
lpDCRect->left, // DestX
lpDCRect->top, // DestY
RECTWIDTH(lpDCRect), // nDestWidth
RECTHEIGHT(lpDCRect), // nDestHeight
lpDIBRect->left, // SrcX
(int)DIBHeight(lpDIBINFOHEADER) -
lpDIBRect->top -
RECTHEIGHT(lpDIBRect), // SrcY
0, // nStartScan
(WORD)DIBHeight(lpDIBINFOHEADER), // nNumScans
lpDIBBits, // lpBits
(LPBITMAPINFO)lpDIBINFOHEADER, // lpBitsInfo
DIB_RGB_COLORS); // wUsage
}
else
{
// 非原始大小,拉伸。
bRet = ::StretchDIBits(hDC, // hDC
lpDCRect->left, // DestX
lpDCRect->top, // DestY
RECTWIDTH(lpDCRect), // nDestWidth
RECTHEIGHT(lpDCRect), // nDestHeight
lpDIBRect->left, // SrcX
lpDIBRect->top, // SrcY
RECTWIDTH(lpDIBRect), // wSrcWidth
RECTHEIGHT(lpDIBRect), // wSrcHeight
lpDIBBits, // lpBits
(LPBITMAPINFO)lpDIBINFOHEADER, // lpBitsInfo
DIB_RGB_COLORS, // wUsage
SRCCOPY); // dwROP
}
// 解除鎖定
::GlobalUnlock((HGLOBAL) hDIB);
// 恢復以前的調色板
if (hOldPal != NULL)
{
::SelectPalette(hDC, hOldPal, TRUE);
}
// 返回
return bRet;
}
/*************************************************************************
*
* 函數名稱:
* CreateDIBPalette()
*
* 參數:
* HDIB hDIB - 指向DIB對象的指針
* CPalette* pPal - 調色板指針
*
* 返回值:
* BOOL - 創建成功返回TRUE,否則返回FALSE。
*
* 說明:
* 創建DIB對象調色板
*
************************************************************************/
BOOL CDIB::CreateDIBPalette(HDIB hDIB, CPalette* pPal)
{
// 指向邏輯調色板的指針
LPLOGPALETTE lpPal;
// 邏輯調色板的句柄
HANDLE hLogPal;
// 調色板的句柄
HPALETTE hPal = NULL;
// 循環變量
int i;
// 顏色表中的顏色數目
int nNumColors;
// 指向DIB的指針
LPBYTE lpbi;
// 指向BITMAPINFO結構的指針(Win3.0)
LPBITMAPINFO lpbmi;
// 指向BITMAPCOREINFO結構的指針
LPBITMAPCOREINFO lpbmc;
// 表明是否是Win3.0 DIB的標記
BOOL bWinStyleDIB;
// 創建結果
BOOL bRet = FALSE;
// 判斷DIB是否為空
if (hDIB == NULL)
{
// 返回FALSE
return FALSE;
}
// 鎖定DIB
lpbi = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 獲取指向BITMAPINFO結構的指針(Win3.0)
lpbmi = (LPBITMAPINFO)lpbi;
// 獲取指向BITMAPCOREINFO結構的指針
lpbmc = (LPBITMAPCOREINFO)lpbi;
// 獲取DIB中顏色表中的顏色數目
nNumColors = DIBNumColors(lpbi);
if (nNumColors != 0)
{
// 分配為邏輯調色板內存
hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)
+ sizeof(PALETTEENTRY)
* nNumColors);
// 如果內存不足,退出
if (hLogPal == 0)
{
// 解除鎖定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回FALSE
return FALSE;
}
lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal);
// 設置版本號
lpPal->palVersion = PALVERSION;
// 設置顏色數目
lpPal->palNumEntries = (WORD)nNumColors;
// 判斷是否是WIN3.0的DIB
bWinStyleDIB = IS_WIN30_DIB(lpbi);
// 讀取調色板
for (i = 0; i < nNumColors; i++)
{
if (bWinStyleDIB)
{
// 讀取紅色分量
lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
// 讀取綠色分量
lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
// 讀取藍色分量
lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
// 保留位
lpPal->palPalEntry[i].peFlags = 0;
}
else
{
// 讀取紅色分量
lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed;
// 讀取綠色分量
lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;
// 讀取紅色分量
lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue;
// 保留位
lpPal->palPalEntry[i].peFlags = 0;
}
}
// 按照邏輯調色板創建調色板,并返回指針
bRet = pPal->CreatePalette(lpPal);
// 解除鎖定
::GlobalUnlock((HGLOBAL) hLogPal);
// 釋放邏輯調色板
::GlobalFree((HGLOBAL) hLogPal);
}
// 解除鎖定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回結果
return bRet;
}
/*************************************************************************
*
* 函數名稱:
* FindDIBBits()
*
* 參數:
* LPBYTE lpbi - 指向DIB對象的指針
*
* 返回值:
* LPBYTE - 指向DIB圖像象素起始位置
*
* 說明:
* 返回DIB圖像象素起始位置
*
************************************************************************/
LPBYTE CDIB::FindDIBBits(LPBYTE lpbi)
{
return (lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi));
}
/*************************************************************************
*
* 函數名稱:
* DIBWidth()
*
* 參數:
* LPBYTE lpbi - 指向DIB對象的指針
*
* 返回值:
* DWORD - DIB位像寬度
*
* 說明:
* 獲取DIB位圖的寬度
*
************************************************************************/
DWORD CDIB::DIBWidth(LPBYTE lpDIB)
{
// 指向BITMAPINFO結構的指針(Win3.0)
LPBITMAPINFOHEADER lpbmi;
// 指向BITMAPCOREINFO結構的指針
LPBITMAPCOREHEADER lpbmc;
// 獲取指針
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
lpbmc = (LPBITMAPCOREHEADER)lpDIB;
// 返回DIB中圖像的寬度
if (IS_WIN30_DIB(lpDIB))
{
// 對于Windows 3.0 DIB,返回lpbmi->biWidth
return lpbmi->biWidth;
}
else
{
// 對于其它格式的DIB,返回lpbmc->bcWidth
return (DWORD)lpbmc->bcWidth;
}
}
/*************************************************************************
*
* 函數名稱:
* DIBHeight()
*
* 參數:
* LPBYTE lpDIB - 指向DIB對象的指針
*
* 返回值:
* DWORD - DIB位圖高度
*
* 說明:
* 獲取DIB位圖高度
*
************************************************************************/
DWORD CDIB::DIBHeight(LPBYTE lpDIB)
{
// 指向BITMAPINFO結構的指針(Win3.0)
LPBITMAPINFOHEADER lpbmi;
// 指向BITMAPCOREINFO結構的指針
LPBITMAPCOREHEADER lpbmc;
// 獲取指針
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
lpbmc = (LPBITMAPCOREHEADER)lpDIB;
// 返回DIB中圖像的寬度
if (IS_WIN30_DIB(lpDIB))
{
// 對于Windows 3.0 DIB,返回lpbmi->biHeight
return lpbmi->biHeight;
}
else
{
// 對于其它格式的DIB,返回lpbmc->bcHeight
return (DWORD)lpbmc->bcHeight;
}
}
/*************************************************************************
*
* 函數名稱:
* PaletteSize()
*
* 參數:
* LPBYTE lpbi - 指向DIB對象的指針
*
* 返回值:
* WORD - DIB中調色板的大小
*
* 說明:
* 返回DIB調色板大小
*
************************************************************************/
WORD CDIB::PaletteSize(LPBYTE lpbi)
{
// 計算DIB中調色板的大小
if (IS_WIN30_DIB (lpbi))
{
//返回顏色數目×RGBQUAD的大小
return (WORD)(DIBNumColors(lpbi) * sizeof(RGBQUAD));
}
else
{
//返回顏色數目×RGBTRIPLE的大小
return (WORD)(DIBNumColors(lpbi) * sizeof(RGBTRIPLE));
}
}
/*************************************************************************
*
* 函數名稱:
* DIBNumColors()
*
* 參數:
* LPBYTE lpbi - 指向DIB對象的指針
*
* 返回值:
* WORD - 返回調色板中顏色的種數
*
* 說明:
* 計算DIB調色板顏色數目
*
************************************************************************/
WORD CDIB::DIBNumColors(LPBYTE lpbi)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -