📄 dib.cpp
字号:
#include "stdafx.h"
#include "DIB.h"
IMPLEMENT_DYNAMIC(CDIB, CGdiObject);
//////////////////////////////////////////////////////////////////////
//
// CDIB
//
// 设备无关位图类(版本1.0)
//
// 完成功能:
// 设备无关位图的创建,显示,读入,保存,捕捉位图
//
// 版本所有: 罗隽,曾志
//
//////////////////////////////////////////////////////////////////////
//构造函数
CDIB::CDIB() : CGdiObject()
{
}
//析购函数
CDIB::~CDIB()
{
DeleteObject();
}
//////////////////////////////////////////////////////////////////
//
// CreateDIB(int cx, int cy, UINT ibitcount, const void* lpBits)
//
// 完成功能:
// 创建DIB位图
//
// 输入参数:
// 图像宽度 cx
// 图像高度 cy
// 图像位数 ibitcount
// 图像数据 lpBits
//
// 返回参数:
// 是否成功
//
//////////////////////////////////////////////////////////////////
//创建DIB位图
BOOL CDIB::CreateDIB(int cx, int cy, UINT ibitcount, const void* lpBits)
{
ASSERT((ibitcount == 1) || (ibitcount == 4) ||
(ibitcount == 8) || (ibitcount == 16)
|| (ibitcount == 24) ||(ibitcount == 32)) ;
// Create a BITMAPINFOHEADER structure to describe the DIB
//创建信息头
int iSize = sizeof(BITMAPINFOHEADER);// + 256*sizeof(RGBQUAD);
BITMAPINFO* pBMI;
BYTE *pByte;
switch(ibitcount){
case 8:
iSize += 4*4;
break;
case 1:
case 4:
case 16:
case 24:
case 32:
break;
default:
break;
}
pByte = new BYTE[iSize];
pBMI = (BITMAPINFO*) pByte;
memset(pBMI, 0, iSize);
pBMI->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pBMI->bmiHeader.biWidth = cx;
pBMI->bmiHeader.biHeight = cy;
pBMI->bmiHeader.biPlanes = 1;
pBMI->bmiHeader.biBitCount = ibitcount;
pBMI->bmiHeader.biCompression = BI_RGB; // to use this flag.
BOOL bRet = CreateDIBIndirect(pBMI, lpBits);
delete[] pByte;
return(bRet);
}
//////////////////////////////////////////////////////////////////
//
// CreateDIBIndirect(LPBITMAPINFO pBMI, const void* lpBits)
//
// 完成功能:
// 创建DIB位图
//
// 输入参数:
// 位图信息结构指针 pBMI
// 图像数据 lpBits
//
// 返回参数:
// 是否成功
//
//////////////////////////////////////////////////////////////////
//创建DIB位图
BOOL CDIB::CreateDIBIndirect(LPBITMAPINFO pBMI, const void* lpBits)
{
//摧毁原对象
if (m_hObject != NULL)
{
DeleteObject();
}
// Create the DIB section.
//创建
CDC *pDC = new CDC;
pDC->CreateCompatibleDC(NULL);
LPVOID pBits;
HBITMAP hDIB = ::CreateDIBSection(pDC->GetSafeHdc(),
pBMI,
DIB_RGB_COLORS,
&pBits,
NULL,
0);
delete pDC;
ASSERT(hDIB);
ASSERT(pBits);
Attach(hDIB);
//拷贝图像数据
SetDIBBits(GetWidthBytes() * GetHeight(), lpBits);
return TRUE;
}
//////////////////////////////////////////////////////////////////
//
// SetDIBBits(DWORD dwCount,const void * lpBits)
//
// 完成功能:
// 设置图像数据,将 lpBits 的数据拷贝至图像
//
// 输入参数:
// 位图数据大小 dwCount
// 图像数据 lpBits
//
// 返回参数:
// 拷贝的数据大小
//
//////////////////////////////////////////////////////////////////
// Set DIB's bits
// 设置图像数据
DWORD CDIB::SetDIBBits(DWORD dwCount,const void * lpBits)
{
if(lpBits != NULL){
LPVOID pBits = GetBits();
memcpy(pBits,lpBits,dwCount);
return dwCount;
}
return 0;
}
//////////////////////////////////////////////////////////////////
//
// GetDIBBits(DWORD dwCount, LPVOID lpBits)
//
// 完成功能:
// 得到图像数据.
// 如果 lpBits 为空,则返回图像数据指针;
// 如果 lpBits 不为空,
// 则将图像数据拷贝至该指针,
// 并返回图像数据指针;
//
// 输入参数:
// 拷贝的位图数据大小 dwCount
// 图像数据 lpBits
//
// 返回参数:
// 图像数据指针
//
//////////////////////////////////////////////////////////////////
// Get DIB's bits
// 得到图像数据
LPVOID CDIB::GetDIBBits(DWORD dwCount, LPVOID lpBits)
{
LPVOID pBits = GetBits();
if(lpBits != NULL){
memcpy(lpBits,pBits,dwCount);
return pBits;
}
else{
return pBits;
}
}
//////////////////////////////////////////////////////////////////
//
// operator = (CDIB& copy)
//
// 完成功能:
// 重载赋值符
//
// 输入参数:
// 要拷贝的位图 copy
//
// 返回参数:
// 新图像数据
//
//////////////////////////////////////////////////////////////////
//重载赋值符
CDIB& CDIB::operator = (CDIB& copy)
{
DIBSECTION DibSection;
//得到原图像信息
copy.GetDibSection(&DibSection);
int nSize = DibSection.dsBmih.biClrUsed*sizeof(RGBQUAD) + sizeof(BITMAPINFOHEADER);
//申请新图像信息头内存
BYTE *pByte = new BYTE[nSize];
//拷贝信息
memcpy(pByte, &(DibSection.dsBmih), sizeof(BITMAPINFOHEADER));
CDC *pdc = copy.GetDC();
//得到调色板信息
::GetDIBColorTable(pdc->GetSafeHdc(), 0, DibSection.dsBmih.biClrUsed,
(RGBQUAD*)(pByte+sizeof(BITMAPINFOHEADER)));
copy.ReleaseDC(pdc);
//创建新位图
BITMAPINFO *pBMI = (BITMAPINFO*)pByte;
CreateDIBIndirect(pBMI);
//拷贝图像信息
int nTotalSize = copy.GetWidthBytes() * copy.GetHeight();
memcpy(GetBits(), copy.GetBits(), nTotalSize);
delete[] pByte;
return(*this);
}
//////////////////////////////////////////////////////////////////
//
// SetPalette(UINT uStartIndex, UINT cEntries, CONST RGBQUAD *pColors)
//
// 完成功能:
// 设置调色板
//
// 输入参数:
// 调色板开始索引 uStartIndex
// 调色板入口 cEntries
// 颜色数据 pColors
//
// 返回参数:
// 无
//
//////////////////////////////////////////////////////////////////
// Set the color table in the DIB section.
// 设置调色板
void CDIB::SetPalette(UINT uStartIndex, UINT cEntries, CONST RGBQUAD *pColors)
{
HDC hdc = ::CreateCompatibleDC(NULL);
HBITMAP hOld = (HBITMAP)::SelectObject(hdc, m_hObject);
::SetDIBColorTable(hdc, uStartIndex, cEntries, pColors);
::SelectObject(hdc, hOld);
::DeleteObject(hdc);
}
//////////////////////////////////////////////////////////////////
//
// SetPalette(CPalette* pPal)
//
// 完成功能:
// 设置调色板
//
// 输入参数:
// 调色板结构指针 pPal
//
// 返回参数:
// 无
//
//////////////////////////////////////////////////////////////////
// 设置调色板
void CDIB::SetPalette(CPalette* pPal)
{
ASSERT(pPal);
// get the colors from the palette
int iColors = 0;
pPal->GetObject(sizeof(iColors), &iColors);
ASSERT(iColors > 0);
PALETTEENTRY* pPE = new PALETTEENTRY[iColors];
pPal->GetPaletteEntries(0, iColors, pPE);
// Build a table of RGBQUADS
RGBQUAD* pRGB = new RGBQUAD[iColors];
ASSERT(pRGB);
for (int i = 0; i < iColors; i++) {
pRGB[i].rgbRed = pPE[i].peRed;
pRGB[i].rgbGreen = pPE[i].peGreen;
pRGB[i].rgbBlue = pPE[i].peBlue;
pRGB[i].rgbReserved = 0;
}
SetPalette(0, iColors, pRGB);
delete [] pRGB;
delete [] pPE;
}
//////////////////////////////////////////////////////////////////
//
// GetDC(void)
//
// 完成功能:
// 得到与位图相关的设备
//
// 输入参数:
// 无
//
// 返回参数:
// 与位图相关的设备指针
//
//////////////////////////////////////////////////////////////////
//得到与位图相关的设备
CDC* CDIB::GetDC(void)
{
CDibDC* pdc = new CDibDC;
if(pdc == NULL)
return(NULL);
pdc->CreateCompatibleDC(NULL);
pdc->m_hOld = (HBITMAP)::SelectObject(pdc->GetSafeHdc(), GetSafeHandle());
return(pdc);
}
//////////////////////////////////////////////////////////////////
//
// ReleaseDC(CDC *pdc)
//
// 完成功能:
// 得到与位图相关的设备
//
// 输入参数:
// 与位图相关的设备
//
// 返回参数:
// 是否成功
//
//////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -