请教个用GDI画图后保存为8位BMP文件时调色板的问题

hgreminem 2010-05-02 01:03:22
小弟用CDC和CBitmap类在内存中画好了一幅图

并且可以将这幅图保存为24位BMP文件

如果是将该图片保存为8位BMP文件(非灰度图)时

调色板该如何设置呢?

8位灰度图的调色板都是一样的

而非灰度图的调色板又该如何创建?

是否有现成的API可以调用呢?

非常谢谢大家的回答,祝大家5.1快乐~~~
...全文
367 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
hgreminem 2010-05-02
  • 打赏
  • 举报
回复
上网找了很久的资料

还是一无所获

不过我自己弄了个算法

采用颜色归类来设置8位BMP的调色板

效果当然没有Fireworks的好

失真挺严重的~~

很感谢回答的朋友们

下面我贴出我自己写的代码

可以将CDC和CBitmap在内存中所画的图片保存为24位或8位的BMP文件

#define BMP_SAVE_TPYE_24 24
#define BMP_SAVE_TPYE_8 8
BOOL SaveToFile(LPCTSTR lpFileName, DWORD dwSaveType/* = BMP_SAVE_TPYE_24*/)
{
CFile file;
BITMAPFILEHEADER bh;
BITMAPINFOHEADER bi;
DWORD dwSize = m_nHeight * m_nWidth * 4, dwNewSize, dwi;
DWORD dwRowOffset = (m_nWidth * 3 + 3) / 4 * 4 - m_nWidth * 3;
BYTE *pData = new BYTE[dwSize];

if (pData == NULL)
{
goto Err;
}

DWORD dwOffset = 0;
dwNewSize = m_pBitmap->GetBitmapBits(dwSize, pData);
if (dwNewSize == 0)
{
goto Err;
}

DWORD dwPixCount = 1;
DWORD dwPaletteSize;
RGBQUAD rgb[256];
if (dwSaveType == BMP_SAVE_TPYE_8)
{
int quadOffset = 50;
int x, y, z;
BYTE B = 0, G = 0, R = 0;
dwi = 0;
for (x = 0; x < 6; x ++)
{
for (y = 0; y < 6; y ++)
{
for (z = 0; z < 6; z ++)
{
rgb[dwi].rgbRed = R;
rgb[dwi].rgbGreen = G;
rgb[dwi++].rgbBlue = B;
B += quadOffset;
}
B = 0;
G += quadOffset;
}
G = 0;
R += quadOffset;
}
for (dwi = 0; dwi < dwNewSize; dwi ++)
{
BYTE B = (pData[dwi++] / quadOffset) * quadOffset;
BYTE G = (pData[dwi++] / quadOffset) * quadOffset;
BYTE R = (pData[dwi++] / quadOffset) * quadOffset;
BOOL fFind = FALSE;
for (x = 0; x < 256; x ++)
{
if (rgb[x].rgbRed == R &&
rgb[x].rgbGreen == G &&
rgb[x].rgbBlue == B)
{
fFind = TRUE;
pData[dwOffset++] = x;
break;
}
}
if (fFind == FALSE)
{
pData[dwOffset++] = 255;
}
if (dwPixCount % m_nWidth == 0)
{
dwOffset += dwRowOffset;
}
dwPixCount ++;
}
dwPaletteSize = 1024;
}
else if (dwSaveType == BMP_SAVE_TPYE_24)
{
for (dwi = 0; dwi < dwNewSize; dwi ++)
{
pData[dwOffset++] = pData[dwi++];
pData[dwOffset++] = pData[dwi++];
pData[dwOffset++] = pData[dwi++];
if (dwPixCount % m_nWidth == 0)
{
dwOffset += dwRowOffset;
}
dwPixCount ++;
}
dwPaletteSize = 0;
}
else
{
goto Err;
}

dwSize = dwOffset;

bh.bfType = 0x4D42;
bh.bfReserved1 = 0;
bh.bfReserved2 = 0;
bh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwSize;
bh.bfOffBits = bh.bfSize - dwSize;

bi.biSize = 40;
bi.biWidth = m_nWidth;
bi.biHeight = -m_nHeight;
bi.biPlanes = 1;
bi.biCompression = BI_RGB;
bi.biClrImportant = 0;
bi.biClrUsed = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biSizeImage = dwSize;
bi.biBitCount = dwSaveType;

try
{
if (file.Open(lpFileName, CFile::modeCreate | CFile::modeReadWrite))
{
file.Write(&bh, sizeof(BITMAPFILEHEADER));
file.Write(&bi, sizeof(BITMAPINFOHEADER));
if (dwSaveType == BMP_SAVE_TPYE_8)
{
file.Write(&rgb[0], 1024);
}
file.Write(pData, dwSize);
file.Close();
delete [] pData;
return TRUE;
}
}
catch (CException* e)
{
e->Delete();
file.Close();
}
Err:
if (pData != NULL)
{
delete [] pData;
}

return FALSE;
}
James__Rose 2010-05-02
  • 打赏
  • 举报
回复
额,上边赋值的时候多加了一个p,不好意思
James__Rose 2010-05-02
  • 打赏
  • 举报
回复
ColorTable=new RGBQUAD[256]; //申请颜色表需要的空间

for( i=0;i<256;i++) //对于256个灰度等级调色板索引进行赋值
{
pColorTable[i].rgbBlue=i;
pColorTable[i].rgbGreen=i;
pColorTable[i].rgbRed=i;
pColorTable[i].rgbReserved=0;
}


对于8位非灰度图,可以不按上述赋值方式,自由选择赋值方式,但是不保证每台机器支持一样的彩色输出效果
尹成 2010-05-02
  • 打赏
  • 举报
回复
慢慢来。。。也在研究这块,共勉。。。顺便顶一下,以期更多前辈来分享自己经验!
jogger007 2010-05-02
  • 打赏
  • 举报
回复
帮顶一下
hgreminem 2010-05-02
  • 打赏
  • 举报
回复
自己顶一下~~~

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧