📄 dibprcs.cpp
字号:
/*************************************************************************
* 文件DIBPrcs.cpp用来存放有关DIB的操作函数
* 文件头存放在GlobalApi.h中
*************************************************************************
*/
#include "GlobalApi.h"
#include "stdafx.h"
#include "cdib.h"
/*************************************************************************
*
* \函数名称:
* GetSystemPalette()
*
* \输入参数:
* 无
*
* \返回值:
* HPALETTE - 系统调色板句柄
*
* \说明:
* 该函数获得当前正在使用的系统调色板的句柄
*
*************************************************************************
*/
HPALETTE GetSystemPalette()
{
// 设备上下文
HDC hDC;
// 声明调色板句柄、指针等临时变量
static HPALETTE hPal = NULL;
HANDLE hLogPal;
LPLOGPALETTE lpLogPal;
// 当前系统调色板的颜色数
int nColors;
// 获得当前系统设备上下文
hDC = GetDC(NULL);
if (!hDC)
return NULL;
// 获得当前系统调色板的颜色数目
nColors = ( 1 << (GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES)));
// 给调色板分配内存
hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) + nColors *
sizeof(PALETTEENTRY));
if (!hLogPal)
return NULL;
// 得到调色板内存指针
lpLogPal = (LPLOGPALETTE)GlobalLock(hLogPal);
// 设置调色板信息
lpLogPal->palVersion = 0x300;
lpLogPal->palNumEntries = nColors;
// 将系统的调色板拷贝到当前的逻辑调色板中
GetSystemPaletteEntries(hDC, 0, nColors,
(LPPALETTEENTRY)(lpLogPal->palPalEntry));
// 创建Windows调色板
hPal = CreatePalette(lpLogPal);
// 释放已分配内存并删除临时对象
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
ReleaseDC(NULL, hDC);
// 返回
return hPal;
}
/*************************************************************************
*
* \函数名称:
* CopyPalette
*
* \输入参数:
* HPALETTE hPalSrc - 需要拷贝的源调色板句柄
*
* \返回值:
* HPALETTE - 如果操作成功,则返回拷贝的调色板句柄
*
* \说明:
* 该函数将创建一个新的调色板,并从指定的调色板拷贝调色板内容
*
*************************************************************************
*/
HPALETTE CopyPalette(HPALETTE hPalSrc)
{
// 调色板指针,临时变量
PLOGPALETTE plogPal;
// 声明一个调色板句柄和一个临时句柄
HPALETTE hPalette;
HANDLE hTemp;
// 调色板表项数
int iNumEntries=0;
// 获取调色板中的表项数
iNumEntries = GetPaletteEntries(hPalSrc, 0, iNumEntries, NULL);
if (iNumEntries == 0)
return (HPALETTE) NULL;
// 分配调色板内存,得到句柄
hTemp = GlobalAlloc(GHND, sizeof(DWORD) + sizeof(PALETTEENTRY)*iNumEntries);
if (! hTemp)
return (HPALETTE) NULL;
// 得到调色板的指针
plogPal = (PLOGPALETTE)GlobalLock(hTemp);
if (! plogPal)
return (HPALETTE) NULL;
// 设置调色板的信息
plogPal->palVersion = 0x300;
plogPal->palNumEntries = (WORD) iNumEntries;
// 获取逻辑调色板中指定范围的调色板表项
GetPaletteEntries(hPalSrc, 0, iNumEntries, plogPal->palPalEntry);
// 创建一个Windows调色板
hPalette = CreatePalette(plogPal);
// 释放以分配的内存
GlobalUnlock( hTemp );
GlobalFree ( hTemp );
return hPalette;
}
/*************************************************************************
*
* \函数名称:
* ReadDIB
*
* \输入参数:
* CFile* pFile - 需要打开的DIB文件
* LPBITMAPINFOHEADER* pLpBMIH - DIB信息头指针的指针
* LPBYTE* pLpImage - DIB位图数据块指针的指针
*
* \返回值:
* BOOL - 如果操作成功,则返回TRUE
*
* \说明:
* 该函数将指定文件中的DIB文件载入,其中信息头和调色板放在*pLpBMIH中
* 图象数据存放到*pLpImage中。
*
*************************************************************************
*/
BOOL ReadDIB(CFile* pFile, LPBITMAPINFOHEADER* pLpBMIH, LPBYTE* pLpImage)
{
// 临时存放信息的变量
int nCount, nSize;
BITMAPFILEHEADER bmfh;
// 信息头指针
//LPBITMAPINFOHEADER lpBMIH;
// DIB图象数据指针
//LPBYTE lpImage;
// 进行读操作
try
{
// 读取文件头
nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
if(nCount != sizeof(BITMAPFILEHEADER)) {
throw new CException;
}
// 如果文件类型部位"BM",则返回并进行相应错误处理
if(bmfh.bfType != 0x4d42) {
throw new CException;
}
// 计算信息头加上调色板的大小,并分配相应的内存
nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
*pLpBMIH = (LPBITMAPINFOHEADER) new char[nSize];
// 读取信息头和调色板
nCount = pFile->Read(*pLpBMIH, nSize);
// 计算图象数据大小并设置调色板指针
if((*pLpBMIH)->biSize != sizeof(BITMAPINFOHEADER)) {
TRACE("Not a valid Windows bitmap -- probably an OS/2 bitmap\n");
throw new CException;
}
// 如果图象数据内存大小为0,则重新计算
if((*pLpBMIH)->biSizeImage == 0) {
DWORD dwBytes = ((DWORD) (*pLpBMIH)->biWidth * (*pLpBMIH)->biBitCount) / 32;
if(((DWORD) (*pLpBMIH)->biWidth * (*pLpBMIH)->biBitCount) % 32) {
dwBytes++;
}
dwBytes *= 4;
(*pLpBMIH)->biSizeImage = dwBytes * (*pLpBMIH)->biHeight;
}
// 分配图象数据内存,并从文件中读取图象数据
*pLpImage = (LPBYTE) new char[(*pLpBMIH)->biSizeImage];
nCount = pFile->Read((*pLpImage), (*pLpBMIH)->biSizeImage);
}
// 错误处理
catch(CException* pe)
{
AfxMessageBox("Read error");
pe->Delete();
return FALSE;
}
// 将指针赋值
// 返回
return TRUE;
}
/*************************************************************************
*
* \函数名称:
* MakeDIBPalette()
*
* \输入参数:
* LPVOID lpvColorTable - 颜色表指针
* LPBITMAPINFOHEADER lpBMIH - DIB信息头指针
*
* \返回值:
* HPALETTE - 如果成功,则调色板句柄
*
* \说明:
* 该函数将读取颜色表,并创建一个Windows调色板,并返回此调色板的句柄
*
************************************************************************
*/
HPALETTE MakeDIBPalette(LPVOID lpvColorTable, LPBITMAPINFOHEADER lpBMIH)
{
// 调色板句柄
HPALETTE hPalette = NULL;
// 颜色表颜色数
int nColorTableEntries;
// 设置DIB中的调色板指针
// lpvColorTable = (LPBYTE) lpBMIH + sizeof(BITMAPINFOHEADER);
// 计算调色板的表项数
if(lpBMIH->biClrUsed == 0) {
switch(lpBMIH->biBitCount) {
case 1:
nColorTableEntries = 2;
break;
case 4:
nColorTableEntries = 16;
break;
case 8:
nColorTableEntries = 256;
break;
case 16:
case 24:
case 32:
nColorTableEntries = 0;
break;
default:
break;
}
}
// 否则调色板的表项数就是用到的颜色数目
else {
nColorTableEntries = lpBMIH->biClrUsed;
}
ASSERT((nColorTableEntries >= 0) && (nColorTableEntries <= 256));
// 如果不存在调色板,则返回FALSE
if(nColorTableEntries == 0) return FALSE;
// 给逻辑调色板分配内存
LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2 * sizeof(WORD) +
nColorTableEntries * sizeof(PALETTEENTRY)];
// 设置逻辑调色板的信息
pLogPal->palVersion = 0x300;
pLogPal->palNumEntries = nColorTableEntries;
// 拷贝DIB中的颜色表到逻辑调色板
LPRGBQUAD pDibQuad = (LPRGBQUAD) lpvColorTable;
for(int i = 0; i < nColorTableEntries; i++) {
pLogPal->palPalEntry[i].peRed = pDibQuad->rgbRed;
pLogPal->palPalEntry[i].peGreen = pDibQuad->rgbGreen;
pLogPal->palPalEntry[i].peBlue = pDibQuad->rgbBlue;
pLogPal->palPalEntry[i].peFlags = 0;
pDibQuad++;
}
// 创建逻辑调色板
hPalette = ::CreatePalette(pLogPal);
// 删除临时变量
delete pLogPal;
// 返回调色板句柄
return hPalette;
}
/*************************************************************************
*
* \函数名称:
* PaintDIB()
*
* \输入参数:
* CDC* pDC - 指向将要接收DIB图象的设备上下文指针
* LPBITMAPINFOHEADER lpBMIH - DIB信息头指针
* LPBYTE lpImage; - DIB位图数据块地址
* CPoint origin - 显示DIB的逻辑坐标
* CSize size - 显示矩形的宽度和高度
* HPALETTE hPalette - 指向DIB的调色板句柄
*
* \返回值:
* BOOL - 如果成功,则返回TRUE
*
* \说明:
* 该函数将DIB图象进行显示
*
************************************************************************
*/
BOOL PaintDIB(CDC* pDC, LPBITMAPINFOHEADER lpBMIH, LPBYTE lpImage, CPoint origin, CSize size, HPALETTE hPalette)
{
if(lpBMIH == NULL) return FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -