急!!彩色bmp图片如何变成黑白图片并存入文件(不显示在窗口中)?

flyboycsdn 2003-08-12 05:10:07
如题
...全文
124 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
ysq1026 2004-02-06
  • 打赏
  • 举报
回复
在对话框中又怎么用呢???
hxy2003 2004-02-05
  • 打赏
  • 举报
回复
圆圆的圆圆的月亮的脸,甜甜的甜甜的鲜灵的汤圆,满满的满满的盛给你一碗,装上我美美的美美的元宵祝愿!
hxy2003 2004-02-03
  • 打赏
  • 举报
回复
up


我也想要
ficher 2004-01-11
  • 打赏
  • 举报
回复
void CCh1_1View::OnFILE256ToGray()
{
// 将256色位图转换成灰度图

// 获取文档
CCh1_1Doc* pDoc = GetDocument();

// 指向DIB的指针
LPSTR lpDIB;

// 锁定DIB
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());

// 颜色表中的颜色数目
WORD wNumColors;

// 获取DIB中颜色表中的颜色数目
wNumColors = ::DIBNumColors(lpDIB);

// 判断是否是8-bpp位图
if (wNumColors != 256)
{
// 提示用户
MessageBox("非256色位图!", "系统提示" , MB_ICONINFORMATION | MB_OK);

// 解除锁定
::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());

// 返回
return;
}

// 更改光标形状
BeginWaitCursor();

// 指向DIB象素指针
LPSTR lpDIBBits;

// 指向DIB象素的指针
BYTE * lpSrc;

// 循环变量
LONG i;
LONG j;

// 图像宽度
LONG lWidth;

// 图像高度
LONG lHeight;

// 图像每行的字节数
LONG lLineBytes;

// 指向BITMAPINFO结构的指针(Win3.0)
LPBITMAPINFO lpbmi;

// 指向BITMAPCOREINFO结构的指针
LPBITMAPCOREINFO lpbmc;

// 表明是否是Win3.0 DIB的标记
BOOL bWinStyleDIB;

// 获取指向BITMAPINFO结构的指针(Win3.0)
lpbmi = (LPBITMAPINFO)lpDIB;

// 获取指向BITMAPCOREINFO结构的指针
lpbmc = (LPBITMAPCOREINFO)lpDIB;

// 灰度映射表
BYTE bMap[256];

// 判断是否是WIN3.0的DIB
bWinStyleDIB = IS_WIN30_DIB(lpDIB);

// 计算灰度映射表(保存各个颜色的灰度值),并更新DIB调色板
for (i = 0; i < 256; i ++)
{
if (bWinStyleDIB)
{
// 计算该颜色对应的灰度值
bMap[i] = (BYTE)(0.299 * lpbmi->bmiColors[i].rgbRed +
0.587 * lpbmi->bmiColors[i].rgbGreen +
0.114 * lpbmi->bmiColors[i].rgbBlue + 0.5);

// 更新DIB调色板红色分量
lpbmi->bmiColors[i].rgbRed = i;

// 更新DIB调色板绿色分量
lpbmi->bmiColors[i].rgbGreen = i;

// 更新DIB调色板蓝色分量
lpbmi->bmiColors[i].rgbBlue = i;

// 更新DIB调色板保留位
lpbmi->bmiColors[i].rgbReserved = 0;
}
else
{
// 计算该颜色对应的灰度值
bMap[i] = (BYTE)(0.299 * lpbmc->bmciColors[i].rgbtRed +
0.587 * lpbmc->bmciColors[i].rgbtGreen +
0.114 * lpbmc->bmciColors[i].rgbtBlue + 0.5);

// 更新DIB调色板红色分量
lpbmc->bmciColors[i].rgbtRed = i;

// 更新DIB调色板绿色分量
lpbmc->bmciColors[i].rgbtGreen = i;

// 更新DIB调色板蓝色分量
lpbmc->bmciColors[i].rgbtBlue = i;
}
}

// 找到DIB图像象素起始位置
lpDIBBits = ::FindDIBBits(lpDIB);

// 获取图像宽度
lWidth = ::DIBWidth(lpDIB);

// 获取图像高度
lHeight = ::DIBHeight(lpDIB);

// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);

// 更换每个象素的颜色索引(即按照灰度映射表换成灰度值)
// 每行
for(i = 0; i < lHeight; i++)
{
// 每列
for(j = 0; j < lWidth; j++)
{
// 指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;

// 变换
*lpSrc = bMap[*lpSrc];
}
}

// 替换当前调色板为灰度调色板
pDoc->GetDocPalette()->SetPaletteEntries(0, 256, (LPPALETTEENTRY) ColorsTable[0]);

// 设置脏标记
pDoc->SetModifiedFlag(TRUE);

// 实现新的调色板
OnDoRealize((WPARAM)m_hWnd,0);

// 更新视图
pDoc->UpdateAllViews(NULL);

// 解除锁定
::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());

// 恢复光标
EndWaitCursor();
}

BOOL WINAPI SaveDIB(HDIB hDib, CFile& file)
{
// Bitmap文件头
BITMAPFILEHEADER bmfHdr;

// 指向BITMAPINFOHEADER的指针
LPBITMAPINFOHEADER lpBI;

// DIB大小
DWORD dwDIBSize;

if (hDib == NULL)
{
// 如果DIB为空,返回FALSE
return FALSE;
}

// 读取BITMAPINFO结构,并锁定
lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);

if (lpBI == NULL)
{
// 为空,返回FALSE
return FALSE;
}

// 判断是否是WIN3.0 DIB
if (!IS_WIN30_DIB(lpBI))
{
// 不支持其它类型的DIB保存

// 解除锁定
::GlobalUnlock((HGLOBAL) hDib);

// 返回FALSE
return FALSE;
}

// 填充文件头

// 文件类型"BM"
bmfHdr.bfType = DIB_HEADER_MARKER;

// 计算DIB大小时,最简单的方法是调用GlobalSize()函数。但是全局内存大小并
// 不是DIB真正的大小,它总是多几个字节。这样就需要计算一下DIB的真实大小。

// 文件头大小+颜色表大小
// (BITMAPINFOHEADER和BITMAPCOREHEADER结构的第一个DWORD都是该结构的大小)
dwDIBSize = *(LPDWORD)lpBI + ::PaletteSize((LPSTR)lpBI);

// 计算图像大小
if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
{
// 对于RLE位图,没法计算大小,只能信任biSizeImage内的值
dwDIBSize += lpBI->biSizeImage;
}
else
{
// 象素的大小
DWORD dwBmBitsSize;

// 大小为Width * Height
dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight;

// 计算出DIB真正的大小
dwDIBSize += dwBmBitsSize;

// 更新biSizeImage(很多BMP文件头中biSizeImage的值是错误的)
lpBI->biSizeImage = dwBmBitsSize;
}


// 计算文件大小:DIB大小+BITMAPFILEHEADER结构大小
bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);

// 两个保留字
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;

// 计算偏移量bfOffBits,它的大小为Bitmap文件头大小+DIB头大小+颜色表大小
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
+ PaletteSize((LPSTR)lpBI);
// 尝试写文件
TRY
{
// 写文件头
file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));

// 写DIB头和象素
file.WriteHuge(lpBI, dwDIBSize);
}
CATCH (CFileException, e)
{
// 解除锁定
::GlobalUnlock((HGLOBAL) hDib);

// 抛出异常
THROW_LAST();
}
END_CATCH

// 解除锁定
::GlobalUnlock((HGLOBAL) hDib);

// 返回TRUE
return TRUE;
}
akiy 2004-01-10
  • 打赏
  • 举报
回复
http://www.vckbase.com/code/downcode.asp?id=1686

19,473

社区成员

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

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