?? dibapi.cpp
字號(hào):
// ************************************************************************
// 文件名:dibapi.cpp
//
// 公用 DIB(Independent Bitmap) API函數(shù)庫(kù):
//
// PaintDIB() - 繪制DIB對(duì)象
// FindDIBBits() - 返回DIB圖像象素起始位置
// DIBWidth() - 返回DIB寬度
// DIBHeight() - 返回DIB高度
// DIBNumColors() - 計(jì)算DIB調(diào)色板顏色數(shù)目
// CopyHandle() - 拷貝內(nèi)存塊
//
// SaveDIB() - 將DIB保存到指定文件中
// ReadDIBFile() - 重指定文件中讀取DIB對(duì)象
// NewDIB() - 根據(jù)提供的寬、高、顏色位數(shù)來(lái)創(chuàng)建一個(gè)新的DIB
//
// PaletteSize() - 返回DIB調(diào)色板大小
//
// ************************************************************************
#include "stdafx.h"
#include "dibapi.h"
#include <io.h>
#include <errno.h>
#include <math.h>
#include <direct.h>
/*
* Dib文件頭標(biāo)志(字符串"BM",寫DIB時(shí)用到該常數(shù))
*/
#define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B')
/*************************************************************************
*
* 函數(shù)名稱:
* PaintDIB()
*
* 參數(shù):
* HDC hDC - 輸出設(shè)備DC
* LPRECT lpDCRect - 繪制矩形區(qū)域
* HDIB hDIB - 指向DIB對(duì)象的指針
* LPRECT lpDIBRect - 要輸出的DIB區(qū)域
* CPalette* pPal - 指向DIB對(duì)象調(diào)色板的指針
*
* 返回值:
* BOOL - 繪制成功返回TRUE,否則返回FALSE。
*
* 說(shuō)明:
* 該函數(shù)主要用來(lái)繪制DIB對(duì)象。其中調(diào)用了StretchDIBits()或者
* SetDIBitsToDevice()來(lái)繪制DIB對(duì)象。輸出的設(shè)備由由參數(shù)hDC指
* 定;繪制的矩形區(qū)域由參數(shù)lpDCRect指定;輸出DIB的區(qū)域由參數(shù)
* lpDIBRect指定。
*
************************************************************************/
BOOL WINAPI PaintDIB(HDC hDC,
LPRECT lpDCRect,
HDIB hDIB,
LPRECT lpDIBRect,
CPalette* pPal)
{
LPSTR lpDIBHdr; // BITMAPINFOHEADER指針
LPSTR lpDIBBits; // DIB象素指針
BOOL bSuccess=FALSE; // 成功標(biāo)志
HPALETTE hPal=NULL; // DIB調(diào)色板
HPALETTE hOldPal=NULL; // 以前的調(diào)色板
// 判斷DIB對(duì)象是否為空
if (hDIB == NULL)
{
// 返回
return FALSE;
}
// 鎖定DIB
lpDIBHdr = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB圖像象素起始位置
lpDIBBits = ::FindDIBBits(lpDIBHdr);
// 獲取DIB調(diào)色板,并選中它
if (pPal != NULL)
{
hPal = (HPALETTE) pPal->m_hObject;
// 選中調(diào)色板
hOldPal = ::SelectPalette(hDC, hPal, TRUE);
}
// 設(shè)置顯示模式
::SetStretchBltMode(hDC, COLORONCOLOR);
// 判斷是調(diào)用StretchDIBits()還是SetDIBitsToDevice()來(lái)繪制DIB對(duì)象
if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) &&
(RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))
{
// 原始大小,不用拉伸。
bSuccess = ::SetDIBitsToDevice(hDC, // hDC
lpDCRect->left, // DestX
lpDCRect->top, // DestY
RECTWIDTH(lpDCRect), // nDestWidth
RECTHEIGHT(lpDCRect), // nDestHeight
lpDIBRect->left, // SrcX
(int)DIBHeight(lpDIBHdr) -
lpDIBRect->top -
RECTHEIGHT(lpDIBRect), // SrcY
0, // nStartScan
(WORD)DIBHeight(lpDIBHdr), // nNumScans
lpDIBBits, // lpBits
(LPBITMAPINFO)lpDIBHdr, // lpBitsInfo
DIB_RGB_COLORS); // wUsage
}
else
{
// 非原始大小,拉伸。
bSuccess = ::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)lpDIBHdr, // lpBitsInfo
DIB_RGB_COLORS, // wUsage
SRCCOPY); // dwROP
}
// 解除鎖定
::GlobalUnlock((HGLOBAL) hDIB);
// 恢復(fù)以前的調(diào)色板
if (hOldPal != NULL)
{
::SelectPalette(hDC, hOldPal, TRUE);
}
// 返回
return bSuccess;
}
/*************************************************************************
*
* 函數(shù)名稱:
* FindDIBBits()
*
* 參數(shù):
* LPSTR lpbi - 指向DIB對(duì)象的指針
*
* 返回值:
* LPSTR - 指向DIB圖像象素起始位置
*
* 說(shuō)明:
* 該函數(shù)計(jì)算DIB中圖像象素的起始位置,并返回指向它的指針。
*
************************************************************************/
LPSTR WINAPI FindDIBBits(LPSTR lpbi)
{
return (lpbi + *(LPDWORD)lpbi + ::PaletteSize(lpbi));
}
/*************************************************************************
*
* 函數(shù)名稱:
* DIBWidth()
*
* 參數(shù):
* LPSTR lpbi - 指向DIB對(duì)象的指針
*
* 返回值:
* DWORD - DIB中圖像的寬度
*
* 說(shuō)明:
* 該函數(shù)返回DIB中圖像的寬度。對(duì)于Windows 3.0 DIB,返回BITMAPINFOHEADER
* 中的biWidth值;對(duì)于其它返回BITMAPCOREHEADER中的bcWidth值。
*
************************************************************************/
DWORD WINAPI DIBWidth(LPSTR lpDIB)
{
// 指向BITMAPINFO結(jié)構(gòu)的指針(Win3.0)
LPBITMAPINFOHEADER lpbmi;
// 指向BITMAPCOREINFO結(jié)構(gòu)的指針
LPBITMAPCOREHEADER lpbmc;
// 獲取指針
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
lpbmc = (LPBITMAPCOREHEADER)lpDIB;
// 返回DIB中圖像的寬度
if (IS_WIN30_DIB(lpDIB))
{
// 對(duì)于Windows 3.0 DIB,返回lpbmi->biWidth
return lpbmi->biWidth;
}
else
{
// 對(duì)于其它格式的DIB,返回lpbmc->bcWidth
return (DWORD)lpbmc->bcWidth;
}
}
/*************************************************************************
*
* 函數(shù)名稱:
* DIBHeight()
*
* 參數(shù):
* LPSTR lpDIB - 指向DIB對(duì)象的指針
*
* 返回值:
* DWORD - DIB中圖像的高度
*
* 說(shuō)明:
* 該函數(shù)返回DIB中圖像的高度。對(duì)于Windows 3.0 DIB,返回BITMAPINFOHEADER
* 中的biHeight值;對(duì)于其它返回BITMAPCOREHEADER中的bcHeight值。
*
************************************************************************/
DWORD WINAPI DIBHeight(LPSTR lpDIB)
{
// 指向BITMAPINFO結(jié)構(gòu)的指針(Win3.0)
LPBITMAPINFOHEADER lpbmi;
// 指向BITMAPCOREINFO結(jié)構(gòu)的指針
LPBITMAPCOREHEADER lpbmc;
// 獲取指針
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
lpbmc = (LPBITMAPCOREHEADER)lpDIB;
// 返回DIB中圖像的寬度
if (IS_WIN30_DIB(lpDIB))
{
// 對(duì)于Windows 3.0 DIB,返回lpbmi->biHeight
return lpbmi->biHeight;
}
else
{
// 對(duì)于其它格式的DIB,返回lpbmc->bcHeight
return (DWORD)lpbmc->bcHeight;
}
}
/*************************************************************************
*
* 函數(shù)名稱:
* DIBNumColors()
*
* 參數(shù):
* LPSTR lpbi - 指向DIB對(duì)象的指針
*
* 返回值:
* WORD - 返回調(diào)色板中顏色的種數(shù)
*
* 說(shuō)明:
* 該函數(shù)返回DIB中調(diào)色板的顏色的種數(shù)。對(duì)于單色位圖,返回2,
* 對(duì)于16色位圖,返回16,對(duì)于256色位圖,返回256;對(duì)于真彩色
* 位圖(24位),沒(méi)有調(diào)色板,返回0。
*
************************************************************************/
WORD WINAPI DIBNumColors(LPSTR lpbi)
{
WORD wBitCount;
// 對(duì)于Windows的DIB, 實(shí)際顏色的數(shù)目可以比象素的位數(shù)要少。
// 對(duì)于這種情況,則返回一個(gè)近似的數(shù)值。
// 判斷是否是WIN3.0 DIB
if (IS_WIN30_DIB(lpbi))
{
DWORD dwClrUsed;
// 讀取dwClrUsed值
dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
if (dwClrUsed != 0)
{
// 如果dwClrUsed(實(shí)際用到的顏色數(shù))不為0,直接返回該值
return (WORD)dwClrUsed;
}
}
// 讀取象素的位數(shù)
if (IS_WIN30_DIB(lpbi))
{
// 讀取biBitCount值
wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;
}
else
{
// 讀取biBitCount值
wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
}
// 按照象素的位數(shù)計(jì)算顏色數(shù)目
switch (wBitCount)
{
case 1:
return 2;
case 4:
return 16;
case 8:
return 256;
default:
return 0;
}
}
/*************************************************************************
*
* 函數(shù)名稱:
* DIBBitCount()
*
* 參數(shù):
* LPSTR lpbi - 指向DIB對(duì)象的指針
*
* 返回值:
* WORD - 返回調(diào)色板中顏色的種數(shù)
*
* 說(shuō)明:
* 該函數(shù)返回DIBBitCount。
*
************************************************************************/
WORD WINAPI DIBBitCount(LPSTR lpbi)
{
WORD wBitCount;
// 讀取象素的位數(shù)
if (IS_WIN30_DIB(lpbi))
{
// 讀取biBitCount值
wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;
}
else
{
// 讀取biBitCount值
wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
}
// 返回wBitCount
return wBitCount;
}
/*************************************************************************
*
* 函數(shù)名稱:
* CopyHandle()
*
* 參數(shù):
* HGLOBAL h - 要復(fù)制的內(nèi)存區(qū)域
*
* 返回值:
* HGLOBAL - 復(fù)制后的新內(nèi)存區(qū)域
*
* 說(shuō)明:
* 該函數(shù)復(fù)制指定的內(nèi)存區(qū)域。返回復(fù)制后的新內(nèi)存區(qū)域,出錯(cuò)時(shí)返回0。
*
************************************************************************/
HGLOBAL WINAPI CopyHandle (HGLOBAL h)
{
if (h == NULL)
return NULL;
// 獲取指定內(nèi)存區(qū)域大小
DWORD dwLen = ::GlobalSize((HGLOBAL) h);
// 分配新內(nèi)存空間
HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen);
// 判斷分配是否成功
if (hCopy != NULL)
{
// 鎖定
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -