📄 cdib.cpp
字号:
::GlobalUnlock(m_hGlobal);
::GlobalFree(m_hGlobal);
}
// 判断DIB对象是否存在
if (m_hDib != NULL)
{
// 解除锁定
::GlobalUnlock(m_hDib);
// 清除DIB对象
::GlobalFree(m_hDib);
}
// 释放图象数据内存
if(m_nImageAlloc == crtAlloc) delete [] m_lpImage;
// 释放调色板句柄
if(m_hPalette != NULL) ::DeleteObject(m_hPalette);
// 如果创建了BITMAP,则进行释放
if(m_hBitmap != NULL) ::DeleteObject(m_hBitmap);
// 重新设置内存分配状态
m_nBmihAlloc = m_nImageAlloc = noAlloc;
// 释放内存后,还需要将指针设置为NULL并将相应的数据设置为0
m_hGlobal = NULL;
m_lpBMIH = NULL;
m_lpImage = NULL;
m_lpvColorTable = NULL;
m_nColorTableEntries = 0;
m_dwSizeImage = 0;
m_lpvFile = NULL;
m_hMap = NULL;
m_hFile = NULL;
m_hBitmap = NULL;
m_hDib = NULL;
m_lpDib = NULL;
m_hPalette = NULL;
}
/*************************************************************************
*
* \函数名称:
* DetachMapFile()
*
* \输入参数:
* 无
*
* \返回值:
* 无
*
* \说明:
* 函数可以释放现有的已分配的内存,并关闭以前关联的任何内存映射文件。
*
************************************************************************
*/
void CDib::DetachMapFile()
{
// 如果没有进行内存映射,则不进行处理
if(m_hFile == NULL) return;
// 关闭内存映射
::UnmapViewOfFile(m_lpvFile);
// 关闭内存映射对象和文件
::CloseHandle(m_hMap);
::CloseHandle(m_hFile);
m_hFile = NULL;
}
/*************************************************************************
*
* \函数名称:
* PaletteSize()
*
* \输入参数:
* 无
*
* \返回值:
* DWORD - 返回调色板的尺寸
*
* \说明:
* 该函数计算机调色板所需的尺寸
*
************************************************************************
*/
WORD CDib::PaletteSize()
{
// 临时变量
WORD NumColors;
LPBITMAPINFOHEADER lpbi=m_lpBMIH;
// 如果biClrUsed为零,且图象象素位数小于8,则计算调色板用到的表项数
NumColors = ((lpbi)->biClrUsed == 0 && (lpbi)->biBitCount <= 8 \
? (int)(1 << (int)(lpbi)->biBitCount) \
: (int)(lpbi)->biClrUsed);
// 根据颜色表示的字节数计算调色板的尺寸
if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
return NumColors * sizeof(RGBTRIPLE);
else
return NumColors * sizeof(RGBQUAD);
}
/*************************************************************************
*
* \函数名称:
* IsEmpty()
*
* \输入参数:
* 无
*
* \返回值:
* BOOL - 如果信息头和图象数据为空,则返回TRUE
*
* \说明:
* 判断信息头和图象数据是否为空
*
************************************************************************
*/
BOOL CDib::IsEmpty()
{
if( m_lpBMIH == NULL&&m_lpImage == NULL)
return TRUE;
else
return FALSE;
}
/*************************************************************************
*
* \函数名称:
* GetDibSaveDim()
*
* \输入参数:
* 无
*
* \返回值:
* CSize - DIB实际存储的高度和宽度
*
* \说明:
* 该函数函数用来得到dib的实际存储宽度(DWORD对齐)
*
************************************************************************
*/
CSize CDib::GetDibSaveDim()
{
CSize sizeSaveDim;
sizeSaveDim.cx = ( m_lpBMIH->biWidth * m_lpBMIH->biBitCount + 31)/32 * 4;
sizeSaveDim.cy = m_lpBMIH->biHeight;
return sizeSaveDim;
}
/*************************************************************************
*
* \函数名称:
* GetPixelOffset()
*
* \输入参数:
* int x - 象素在X轴的坐标
* int y - 象素在Y轴的坐标
*
* \返回值:
* int - 返回象素在图象数据块中的真实地址
*
* \说明:
* 该函数得到坐标为(x,y)的象素点的真实地址。由于DIB结构中对图象数据排列的
* 方式为从下到上,从左到右的,所以需要进行转换。
*
************************************************************************
*/
LONG CDib::GetPixelOffset(int x, int y)
{
CSize sizeSaveDim;
sizeSaveDim = GetDibSaveDim();
LONG lOffset = (LONG) (sizeSaveDim.cy - y - 1) * sizeSaveDim.cx +
x / (8 / m_lpBMIH->biBitCount);
return lOffset;
}
/*************************************************************************
*
* \函数名称:
* GetPixel()
*
* \输入参数:
* int x - 象素在X轴的坐标
* int y - 象素在Y轴的坐标
*
* \返回值:
* RGBQUAD - 返回DIB在该点真实的颜色
*
* \说明:
* 该函数得到DIB图象在该点真是的颜色。
*
************************************************************************
*/
RGBQUAD CDib::GetPixel(int x, int y)
{
// 颜色结构
RGBQUAD cColor;
// 根据每象素比特数得到此点的象素值
switch (m_lpBMIH->biBitCount)
{
case 1 :
if (1<<(7-x%8) & *(LPBYTE)(m_lpImage+GetPixelOffset(x, y)))
{
cColor.rgbBlue = 255;
cColor.rgbGreen = 255;
cColor.rgbRed = 255;
cColor.rgbReserved =0;
}
else
{
cColor.rgbBlue = 0;
cColor.rgbGreen = 0;
cColor.rgbRed = 0;
cColor.rgbReserved =0;
}
break;
case 4 :
{
int nIndex = (*(LPBYTE)(m_lpImage+GetPixelOffset(x, y)) &
(x%2 ? 0x0f : 0xf0)) >> (x%2 ? 0 : 4);
LPRGBQUAD pDibQuad = (LPRGBQUAD) (m_lpvColorTable) + nIndex;
cColor.rgbBlue = pDibQuad->rgbBlue;
cColor.rgbGreen = pDibQuad->rgbGreen;
cColor.rgbRed = pDibQuad->rgbRed;
cColor.rgbReserved =0;
}
break;
case 8 :
{
int nIndex = *(BYTE*)(m_lpImage+GetPixelOffset(x, y));
LPRGBQUAD pDibQuad = (LPRGBQUAD) (m_lpvColorTable) + nIndex;
cColor.rgbBlue = pDibQuad->rgbBlue;
cColor.rgbGreen = pDibQuad->rgbGreen;
cColor.rgbRed = pDibQuad->rgbRed;
cColor.rgbReserved =0;
}
break;
default:
int nIndex = *(BYTE*)(m_lpImage+GetPixelOffset(x, y));
cColor.rgbRed = m_lpImage[nIndex];
cColor.rgbGreen = m_lpImage[nIndex + 1];
cColor.rgbBlue = m_lpImage[nIndex + 2];
cColor.rgbReserved =0;
break;
}
// 返回颜色结构
return cColor;
}
/*************************************************************************
*
* \函数名称:
* GetSystemPalette()
*
* \输入参数:
* 无
*
* \返回值:
* HPALETTE - 系统调色板句柄
*
* \说明:
* 该函数获得当前正在使用的系统调色板的句柄
*
*************************************************************************
*/
HPALETTE CDib::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 CDib::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 CDib::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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -