📄 ddb.cpp
字号:
if(pPE == NULL)return;
pPalette->GetPaletteEntries(0, 256, pPE);
for(int j = 0; j < 256; j++)
{
pRGBQuad[j].rgbRed = pPE[j].peRed;
pRGBQuad[j].rgbGreen = pPE[j].peGreen;
pRGBQuad[j].rgbBlue = pPE[j].peBlue;
}
delete[] pPE;
delete pPalette;
//////////////////////////////////////////////////////
//第三步, 填充与位图相关的结构
//宽度字节数
DWORD dwDibWidthBytes = ((w * 8 + 31) / 32) * 4;
//位图数据大小
DWORD dwDibBitsSize = dwDibWidthBytes * h;
//计算整个Dib文件的大小dwFileSize
DWORD dwFileSize = sizeof(BITMAPFILEHEADER)
+ sizeof(BITMAPINFOHEADER)
+ 256 * sizeof(RGBQUAD)
+ dwDibBitsSize;
//计算位图信息到位图数据间的偏移量(字节)
DWORD dwOffBits = sizeof(BITMAPFILEHEADER)
+ sizeof(BITMAPINFOHEADER)
+ 256 * sizeof(RGBQUAD);
//位图文件头结构和位图信息结构
BITMAPFILEHEADER bmFileHeader;
BITMAPINFOHEADER bmInfo;
//填充BITMAPFILEHEADER结构
bmFileHeader.bfType=0x4d42;
bmFileHeader.bfSize = dwFileSize;
bmFileHeader.bfReserved1 = 0;
bmFileHeader.bfReserved2 = 0;
bmFileHeader.bfOffBits = dwOffBits;
//填充BITMAPINFOHEADER结构
bmInfo.biSize = sizeof(BITMAPINFOHEADER);
bmInfo.biWidth = w;
bmInfo.biHeight = h;
bmInfo.biPlanes = 1;
bmInfo.biBitCount = 8;
bmInfo.biCompression = 0;
bmInfo.biSizeImage = 0;
bmInfo.biXPelsPerMeter = 0;
bmInfo.biYPelsPerMeter = 0;
bmInfo.biClrUsed = 0;
bmInfo.biClrImportant = 0;
//第四步, 写数据
//////////////////////////////////////////////////////
try
{
// 请创建自己的目录或获取当前目录:
CFile file((LPCTSTR )pszDibFileName, CFile::modeCreate |
CFile::modeReadWrite | CFile::shareExclusive);
//写入文件头和位图信息
file.Write((LPSTR)&bmFileHeader, sizeof(BITMAPFILEHEADER));
file.Write((LPSTR)&bmInfo, sizeof(BITMAPINFOHEADER));
//写入数据
file.Write((LPSTR)pRGBQuad, 256 * sizeof(RGBQUAD));
delete[] pRGBQuad;
pRGBQuad = NULL;
//数据索引(行头)
DWORD dwBaseIndex = (DWORD)(h - 1) * dwWidthBytes8;
UINT nZero = dwDibWidthBytes - dwWidthBytes8;
BYTE abyZero[] = {0, 0};
for(int i = 0; i < h ; i++)
{
BYTE* pDibBits8 = pbyDdbBits8 + dwBaseIndex;
file.Write((LPSTR)pDibBits8, dwWidthBytes8);
if(nZero > 0)file.Write((LPSTR)abyZero, 2);
dwBaseIndex -= dwWidthBytes8;
}//end i
file.Close();
}//end try
catch(CFileException* e)
{
e->Delete();
}
if(pRGBQuad)delete[] pRGBQuad;
delete[] pbyDdbBits24;
delete[] pbyDdbBits8;
AfxGetApp()->EndWaitCursor();
}
//获取子区域的数据, 可以反复调用该函数,
//获取24位格式的数据, 即任何格式的像素数据均被转化为24位格式.存储于lpbyBits24中
//存放顺序:蓝----绿----红
void CDdb::GetDdbDataTo24( int x, int y, int nWidth, int nHeight, LPBYTE lpbyBits24)
{
ASSERT(lpbyBits24);
//首先进行参数合法性检测
if((x > m_nWidth - 1) || (y > nHeight - 1))
{
AfxMessageBox("Cross the border!");
return;
}
//最后有效宽度和高度:w , h.
LONG w = (LONG)min(nWidth, m_nWidth - x);
LONG h = (LONG)min(nHeight, m_nHeight - y);
//转换成24位后, 每行的大小和总的数据量
DWORD dwWidthBytes24 = ((w * 24 + 15) / 16) * 2;
//第二步, 将其转化为24位格式.
switch(m_nBitCount)
{
case 8:
{
//为8位显示模式准备调色盘
RGBQUAD* pRGBQuad = new RGBQUAD[256];
if(pRGBQuad == NULL)return ;
//初始化为0
memset(pRGBQuad, 0, 256 * sizeof(RGBQUAD));
//创建表项
GetSystemPaletteEntries(pRGBQuad);
//数据索引基数, 从上往下读
DWORD dwBaseIndex = y * m_nDdbWidthBytes + x;
DWORD dwBase24 = 0;
for(LONG i = 0; i < h; i++)
{
//指向行头的指针, ddb.
BYTE* pbyDdbRaw = m_pDdbData + dwBaseIndex;
//指向行头的指针, 24位.
BYTE* pbyBits24Raw = lpbyBits24 + dwBase24;
for(LONG j = 0; j < w; j++)
{
BYTE byPixel = *(pbyDdbRaw++);
*(pbyBits24Raw++) = pRGBQuad[byPixel].rgbBlue;
*(pbyBits24Raw++) = pRGBQuad[byPixel].rgbGreen;
*(pbyBits24Raw++) = pRGBQuad[byPixel].rgbRed;
}//end j
dwBaseIndex += m_nDdbWidthBytes;
dwBase24 += dwWidthBytes24;
}//end i
delete[] pRGBQuad;
break;
}
case 24:
{
//每行数据个数(字节)
DWORD dwLength = w * 3;
BYTE* pbyDdbRaw = m_pDdbData + y * m_nDdbWidthBytes + x + x + x;
//指向行头的指针, 24位.
BYTE* pbyBits24Raw = lpbyBits24;
for(LONG i = 0; i < h; i++)
{
::CopyMemory(pbyBits24Raw, pbyDdbRaw, dwLength);
pbyDdbRaw += m_nDdbWidthBytes; //from
pbyBits24Raw += dwWidthBytes24; //to
}
break;
}//end case
case 16:
case 32:
{
//数据索引基数, 从上往下读
DWORD dwBaseIndex = y * m_nDdbWidthBytes + ((m_nBitCount == 16) ? (x + x) : (4 * x));
DWORD dwBase24 = 0;
for( LONG i = 0; i < h; i++)
{
//指向行头的指针, ddb.
BYTE* pbyDdbRaw = m_pDdbData + dwBaseIndex;
//从上往下
DWORD dwBitsIndex24 = (DWORD)(i * dwWidthBytes24);
//指向行头的指针, 24位.
BYTE* pbyBits24Raw = lpbyBits24 + dwBase24;
for(LONG j = 0; j < w; j++)
{
//处理16位
if(m_nBitCount == 16)
{
//记录一个像素点的24位颜色值(16位和32位模式均被转化为24位)
BYTE* pbyRGB = new BYTE[3];
WORD* pwDdbData_16 = (WORD*)(pbyDdbRaw++);
GetRGB16(pbyRGB, pwDdbData_16);
pbyDdbRaw++;
//蓝--绿--红
*pbyBits24Raw++ = pbyRGB[0]; //蓝色
*pbyBits24Raw++ = pbyRGB[1]; //绿色
*pbyBits24Raw++ = pbyRGB[2]; //红色
delete[] pbyRGB;
}
//处理32位
if(m_nBitCount == 32)
{
//蓝--绿--红
*pbyBits24Raw++ = *pbyDdbRaw++; //蓝色
*pbyBits24Raw++ = *pbyDdbRaw++; //绿色
*pbyBits24Raw++ = *pbyDdbRaw++; //红色
pbyDdbRaw++;
}
}//end j
dwBaseIndex += m_nDdbWidthBytes;
dwBase24 += dwWidthBytes24;
}//end i
break;
}//end case
}//end switch
}
//获取子区域的数据, 可以反复调用该函数,
//获取32位格式的数据, 即任何格式的像素数据均被转化为32位格式.存储于lpbyBits32中
//颜色数据存放顺序:蓝--绿--红--**
void CDdb::GetDdbDataTo32( int x, int y, int nWidth, int nHeight, LPBYTE lpbyBits32)
{
ASSERT(lpbyBits32);
//首先进行参数合法性检测
if((x > m_nWidth - 1) || (y > nHeight - 1))
{
AfxMessageBox("Cross the border!");
return;
}
//最后有效宽度和高度:w , h.
LONG w = (LONG)min(nWidth, m_nWidth - x);
LONG h = (LONG)min(nHeight, m_nHeight - y);
//转换成32位后, 每行的大小和总的数据量:字节
DWORD dwWidthBytes32 = w * 4;
//第二步, 将其转化为32位格式.
switch(m_nBitCount)
{
case 8:
{
//为8位显示模式准备调色盘
RGBQUAD* pRGBQuad = new RGBQUAD[256];
if(pRGBQuad == NULL)return ;
//初始化为0
memset(pRGBQuad, 0, 256 * sizeof(RGBQUAD));
//创建表项
GetSystemPaletteEntries(pRGBQuad);
//数据索引基数, 从上往下读
//指向源数据
DWORD dwBaseIndex = y * m_nDdbWidthBytes + x;
//指向32位数据
DWORD dwBase32 = 0;
for(LONG i = 0; i < h; i++)
{
//指向行头的指针, ddb.
BYTE* pbyDdbRaw = m_pDdbData + dwBaseIndex;
//指向行头的指针, 32位.
BYTE* pbyBits32Raw = lpbyBits32 + dwBase32;
for(LONG j = 0; j < w; j++)
{
BYTE byPixel = *(pbyDdbRaw++);
//蓝--绿--红--**
*(pbyBits32Raw++) = pRGBQuad[byPixel].rgbBlue;
*(pbyBits32Raw++) = pRGBQuad[byPixel].rgbGreen;
*(pbyBits32Raw++) = pRGBQuad[byPixel].rgbRed;
pbyBits32Raw++;
}//end j
dwBaseIndex += m_nDdbWidthBytes;
dwBase32 += dwWidthBytes32;
}//end i
delete[] pRGBQuad;
break;
}
case 24:
{
//数据索引基数, 从上往下读
DWORD dwBaseIndex = y * m_nDdbWidthBytes + x + x + x;
//指向32位数据
DWORD dwBase32 = 0;
for(LONG i = 0; i < h; i++)
{
//指向行头的指针, ddb.
BYTE* pbyDdbRaw = m_pDdbData + dwBaseIndex;
//指向行头的指针, 24位.
BYTE* pbyBits32Raw = lpbyBits32 + dwBase32;
for(LONG j = 0; j < w; j++)
{
//蓝--绿--红--**
*(pbyBits32Raw++) = *(pbyDdbRaw++); //b
*(pbyBits32Raw++) = *(pbyDdbRaw++); //g
*(pbyBits32Raw++) = *(pbyDdbRaw++); //r
pbyBits32Raw++; //a
}//end j
dwBaseIndex += m_nDdbWidthBytes;
dwBase32 += dwWidthBytes32;
}
break;
}//end case
case 16:
{
//数据索引基数, 从上往下读
DWORD dwBaseIndex = y * m_nDdbWidthBytes + x + x;
//指向32位数据
DWORD dwBase32 = 0;
for( LONG i = 0; i < h; i++)
{
//指向行头的指针, ddb.
BYTE* pbyDdbRaw = m_pDdbData + dwBaseIndex;
//从上往下
DWORD dwBitsIndex32 = (DWORD)(i * dwWidthBytes32);
//指向行头的指针, 32位.
BYTE* pbyBits32Raw = lpbyBits32 + dwBase32;
for(LONG j = 0; j < w; j++)
{
//处理16位
//记录一个像素点的32位颜色值(16位和32位模式均被转化为24位)
BYTE* pbyRGB = new BYTE[3];
WORD* pwDdbData_16 = (WORD*)(pbyDdbRaw++);
GetRGB16(pbyRGB, pwDdbData_16);
pbyDdbRaw++;
//蓝--绿--红--**
*pbyBits32Raw++ = pbyRGB[0]; //b
*pbyBits32Raw++ = pbyRGB[1]; //g
*pbyBits32Raw++ = pbyRGB[2]; //r
pbyBits32Raw++; //a
delete[] pbyRGB;
}//end j
dwBaseIndex += m_nDdbWidthBytes;
dwBase32 += dwWidthBytes32;
}//end i
break;
}//end case 16
case 32:
{
DWORD dwLength = w * 4;
//数据索引基数, 从上往下读
DWORD dwBaseIndex = y * m_nDdbWidthBytes + 4 * x;
//指向行头的指针, ddb.
BYTE* pbyDdbRaw = m_pDdbData + dwBaseIndex;
BYTE* pbyBits32Raw = lpbyBits32;
for( LONG i = 0; i < h; i++)
{
::CopyMemory(pbyBits32Raw, pbyDdbRaw, dwLength);
pbyDdbRaw += m_nDdbWidthBytes;
pbyBits32Raw += dwWidthBytes32;
}//end i
break;
}//end case 32
}//end switch
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -