📄 dib.cpp
字号:
BOOL CDib::SaveToDib(BYTE *lpDib)
{
if (m_lpBits == NULL)
return FALSE;
// 获取位图数据
BYTE *lp = lpDib;
// 计算位图每行像素所占的字节数
int nByteWidth = BytePerLine(m_nWidth, m_nBitCount);
// 填充位图信息头结构—指定位图的大小和颜色信息
BITMAPINFOHEADER bih;
// 指定位图信息头结构的大小
bih.biSize = sizeof(BITMAPINFOHEADER);
// 指定位图的宽度
bih.biWidth = m_nWidth;
// 指定位图的高度
bih.biHeight = m_nHeight;
// 目标设备的位面数,总为1
bih.biPlanes = 1;
// 指定表示颜色时用到的位数
bih.biBitCount = m_nBitCount;
// 指定为没有压缩的图像数据
bih.biCompression = BI_RGB;
// 指定实际的位图数据占用的字节数
// 使用BI_RGB格式时,设置为0
bih.biSizeImage = 0;
// 指定目标设备的分辨率
bih.biXPelsPerMeter = bih.biYPelsPerMeter = 0;
// 指定位图实际使用的颜色索引数,设置为0表明使用所有调色板项
bih.biClrUsed = 0;
// 指定对图像显示有重要影响的颜色索引数,设置为0表明所有的都重要
bih.biClrImportant = 0;
// 将位图信息头结构的而数据复制到位图数据中
memcpy(lp, &bih, sizeof(BITMAPINFOHEADER));
// 移动位图数据指针到位图信息头之后
lp += sizeof(BITMAPINFOHEADER);
// 如果不是24位真彩色位图将调色板信息写入文件
if (m_nBitCount != 24)
{
// 将调色板信息复制到位图数据中
memcpy(lp, m_lpPatte, PaletteSize(m_nBitCount) * sizeof(RGBQUAD));
// 移动位图数据指针到调色板信息之后
lp += PaletteSize(m_nBitCount) * sizeof(RGBQUAD);
}
// 将位图数据写入文件
memcpy(lp, m_lpBits, nByteWidth * m_nHeight);
return TRUE;
}
BOOL CDib::Copy()
{
// 如果没有位图信息则返回
if (m_lpBits == NULL)
return FALSE;
// 如果无法打开剪贴板则返回
if (!OpenClipboard(NULL))
return FALSE;
// 清空剪贴板,释放剪贴板上的数据
// 使当前程序获得剪贴板的控制权
EmptyClipboard();
HGLOBAL hMem;
BYTE *lpDib;
// 计算位图数据所占的字节数
int nLen = sizeof(BITMAPINFOHEADER)
+ BytePerLine(m_nWidth, m_nBitCount) * m_nHeight;
// 如果不是24位真彩色位图,要加上调色板信息数据的长度
if (m_nBitCount != 24)
nLen += PaletteSize(m_nBitCount) * sizeof(RGBQUAD);
// 为位图数据分配内存
hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, nLen);
// 锁住分配的内存空间
lpDib = (BYTE*)GlobalLock(hMem);
// 将CDIb类的数据结构中的数据转换为DIB位图格式数据
SaveToDib(lpDib);
// 为锁住的内存空间解锁
GlobalUnlock(hMem);
// 将数据按照DIB位图格式复制到剪贴板
SetClipboardData(CF_DIB, hMem);
// 关闭剪贴板
CloseClipboard();
return TRUE;
}
BOOL CDib::Paste()
{
HGLOBAL hMem;
BYTE *lpDib;
// 如果无法打开剪贴板则返回
if (!OpenClipboard(NULL))
return FALSE;
// 如果不能从剪贴板获得位图数据则返回
if (!(hMem = GetClipboardData(CF_DIB)))
return FALSE;
// 锁住分配的内存空间
lpDib = (BYTE*)GlobalLock(hMem);
LoadDib(lpDib);
// 为锁住的内存空间解锁
GlobalUnlock(hMem);
// 关闭剪贴板
CloseClipboard();
return TRUE;
}
int CDib::Stretch(HDC hDC, int XDest, int YDest, int nDestWidth, int nDestHeight,
int XSrc, int YSrc, int nSrcWidth, int nSrcHeight, UINT iUsage, DWORD dwRop)
{
BITMAPINFO *pBI;
// 位图的颜色数
int nPaletteSize = PaletteSize(m_nBitCount);
// 为位图数据分配空间
pBI =(BITMAPINFO *)new BYTE[sizeof(BITMAPINFO) + sizeof(RGBQUAD) * nPaletteSize];
// 将调色板信息拷贝到位图信息结构中
memcpy(pBI->bmiColors, m_lpPatte, sizeof(RGBQUAD) * nPaletteSize);
// 指定位图信息头大小
pBI->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
// 指定位图的宽度
pBI->bmiHeader.biWidth = m_nWidth;
// 指定位图的高度
pBI->bmiHeader.biHeight = m_nHeight;
// 指定位图信息头的位面数
pBI->bmiHeader.biPlanes = 1;
// 指定表示颜色是用的位数
pBI->bmiHeader.biBitCount = m_nBitCount;
// 指定采用不压缩的方式
pBI->bmiHeader.biCompression = BI_RGB;
// 指定实际的位图数据占用的字节数
// 使用BI_RGB格式时,设置为0
pBI->bmiHeader.biSizeImage = 0;
// 设定设备的分辨率
pBI->bmiHeader.biXPelsPerMeter = pBI->bmiHeader.biYPelsPerMeter = 0;
// 指定位图实际使用的颜色索引数,设置为0表明使用所有调色板项
// 指定对图像显示有重要影响的颜色索引数,设置为0表明所有的都重要
pBI->bmiHeader.biClrUsed = pBI->bmiHeader.biClrImportant = 0;
// 设置画位图的模式
// COLORONCOLOR指定为删除像素的模式
SetStretchBltMode(hDC, COLORONCOLOR);
// 在指定的位置画出位图
int ret = StretchDIBits(hDC, XDest, YDest, nDestWidth, nDestHeight,
XSrc, YSrc, nSrcWidth, nSrcHeight, m_lpBits, pBI, iUsage, dwRop);
// 释放内存空间
delete[] pBI;
return ret;
}
BOOL CDib::Gray()
{
if (m_lpBits == NULL)
return FALSE;
int x,y, nByteWidth, nPaletteSize, gray;
BYTE *lp;
m_IsGrayed = FALSE;
// 如果是24位真彩色位图
if (m_nBitCount == 24)
{
nByteWidth = BytePerLine(m_nWidth, m_nBitCount);
for(y=0; y<m_nHeight; ++y)
for (x=0; x<m_nWidth; ++x)
{
// 找到该像素在图像数据数组中的位置
// 如果是24位真彩色位图,每个像素占3字节
lp = m_lpBits + nByteWidth * y + x * 3;
// 修改像素颜色,使其灰度化
gray = (BYTE)(0.299 * lp[2] + 0.587 * lp[1] + 0.114 * lp[0]);
lp[0] = lp[1] = lp[2] = gray;
}
}
else // 不是24为真彩色位图,修改调色板信息来实现灰度化
{
nPaletteSize = PaletteSize(m_nBitCount);
for (x=0; x<nPaletteSize; ++x)
{
// 获得每种颜色数据在调色板中的位置
// 每种颜色在调色板中占4字节
lp = m_lpPatte + x * 4;
// 修改像素颜色,使其灰度化
gray = (BYTE)(0.299 * lp[2] + 0.587 * lp[1] + 0.114 * lp[0]);
lp[0] = lp[1] = lp[2] = gray;
}
}
m_IsGrayed =TRUE;
return TRUE;
}
BOOL CDib::Pixel()
{
if (m_lpBits == NULL && !m_IsGrayed)
return FALSE;
int x,y, nByteWidth, nPaletteSize, pixel;
BYTE *lp;
// 如果是24位真彩色位图
if (m_nBitCount == 24)
{
nByteWidth = BytePerLine(m_nWidth, m_nBitCount);
for(y=0; y<m_nHeight; ++y)
for (x=0; x<m_nWidth; ++x)
{
// 找到该像素在图像数据数组中的位置
// 如果是24位真彩色位图,每个像素占3字节
lp = m_lpBits + nByteWidth * y + x * 3;
// 修改像素颜色,使其灰度化
pixel = (lp[0] > 220) ? 250 : 0;
lp[0] = lp[1] = lp[2] = pixel;
}
}
else // 不是24为真彩色位图,修改调色板信息来实现灰度化
{
nPaletteSize = PaletteSize(m_nBitCount);
for (x=0; x<nPaletteSize; ++x)
{
// 获得每种颜色数据在调色板中的位置
// 每种颜色在调色板中占4字节
lp = m_lpPatte + x * 4;
// 修改像素颜色,使其灰度化
pixel = (lp[0] > 220) ? 250 : 0;
lp[0] = lp[1] = lp[2] = pixel;
}
}
m_IsPixeled =TRUE;
return TRUE;
}
BOOL CDib::RemoveScatterNoise()
{
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -