真彩色位图(BMP)文件如何转换为256色位图?在线等待

albert 2002-09-24 04:08:50
我有一个真彩色位图文件(A.BMP),现在想把它转换成256色的位图文件(B.BMP),请问如何实现?
...全文
1509 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
paul2002 2002-09-25
  • 打赏
  • 举报
回复
楼主要的是灰度图吗?是的话,rujor(rujor)的可以,不过他的是16位的,还有处理24位的,实际上只是把真彩图的每个象素的R,G,B三色用(r*0.29900 + g*0.58700 + b*0.11400)转一下换成在256色表中的索引。
如果是降色的话,算法比较繁了。
albert 2002-09-25
  • 打赏
  • 举报
回复
oldworm(oldworm),我还没有试出来,或者你告诉我如何调用你的那些函数吧。
我现在有一幅图(C:\A.bmp),它是真彩格式,怎么变成256色的图(C:\B.bmp)?
albert 2002-09-25
  • 打赏
  • 举报
回复
谢谢rujor(rujor),但是运行不是很理想。
rujor 2002-09-25
  • 打赏
  • 举报
回复
http://www.enwww.net/mysoftware/64kbmp2gray.zip
借花
albert 2002-09-25
  • 打赏
  • 举报
回复
oldworm(oldworm):是啊!我再试试看,谢谢!!
lchlovely 2002-09-25
  • 打赏
  • 举报
回复
oldworm 2002-09-25
  • 打赏
  • 举报
回复
int GetDIBPixelSize(const BITMAPINFOHEADER & bmih)
{
if ( bmih.biSizeImage )
return bmih.biSizeImage;
else
return ( bmih.biWidth * bmih.biBitCount + 31 ) / 32 * 4 * bmih.biPlanes * abs(bmih.biHeight);
}

int GetDIBColorCount(const BITMAPINFOHEADER & bmih)
{
if ( bmih.biBitCount <= 8 )
if ( bmih.biClrUsed )
return bmih.biClrUsed;
else
return 1 << bmih.biBitCount;
else if ( bmih.biCompression==BI_BITFIELDS )
return 3 + bmih.biClrUsed;
else
return bmih.biClrUsed;
}

Release修改为:
::ReleaseDC

你是不是将代码拆开了拿到你的程序中调用的?
albert 2002-09-25
  • 打赏
  • 举报
回复
romanticist(让我拥抱你入梦),为什么在MSDN里找不到?是用户自己定义的吗?
romanticist 2002-09-25
  • 打赏
  • 举报
回复
这 几 个 本 来 是 定 义 在 宏 里 的 函 数
albert 2002-09-25
  • 打赏
  • 举报
回复
oldworm(oldworm),编译后有以下三个错误:

error C2065: 'GetDIBColorCount' : undeclared identifier
error C2065: 'GetDIBPixelSize' : undeclared identifier
error C2660: 'ReleaseDC' : function does not take 2 parameters

何解?
albert 2002-09-25
  • 打赏
  • 举报
回复
谢谢各位!我已经在以下网址找到正确的方法,不敢独享:

http://msdn.microsoft.com/code/default.asp?url=/msdn-files/026/000/209/Source%20Files/AOTBLOBDlg_cpp.asp


当然,分数还是照给不误!

谢谢捧场!!!
albert 2002-09-25
  • 打赏
  • 举报
回复
paul2002():不是灰度图图,你有24位转为8位的例程吗?

oldworm(oldworm):还是不行啊!?
albert 2002-09-24
  • 打赏
  • 举报
回复
谢谢oldworm(oldworm),我试过OK后,马上给分!
oldworm 2002-09-24
  • 打赏
  • 举报
回复
1、mspaint打开,另存为256色bmp.
2、HBITMAP LoadBitmap(
HINSTANCE hInstance, // handle to application instance
LPCTSTR lpBitmapName // address of bitmap resource name
);

BITMAPINFO * BitmapToDIB(HPALETTE hPal, // palette for color conversion
HBITMAP hBmp, // DDB for convert
int nBitCount, int nCompression) // format wanted
{
typedef struct
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[256+3];
} DIBINFO;

BITMAP ddbinfo;
DIBINFO dibinfo;

// retrieve DDB information
if ( GetObject(hBmp, sizeof(BITMAP), & ddbinfo)==0 )
return NULL;

// fill out BITMAPINFOHEADER based on size and required format
memset(&dibinfo, 0, sizeof(dibinfo));

dibinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
dibinfo.bmiHeader.biWidth = ddbinfo.bmWidth;
dibinfo.bmiHeader.biHeight = ddbinfo.bmHeight;
dibinfo.bmiHeader.biPlanes = 1;
dibinfo.bmiHeader.biBitCount = nBitCount;
dibinfo.bmiHeader.biCompression = nCompression;

HDC hDC = GetDC(NULL); // screen DC
HGDIOBJ hpalOld;

if ( hPal )
hpalOld = SelectPalette(hDC, hPal, FALSE);
else
hpalOld = NULL;

// query GDI for image size
GetDIBits(hDC, hBmp, 0, ddbinfo.bmHeight, NULL, (BITMAPINFO *) & dibinfo, DIB_RGB_COLORS);

int nInfoSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * GetDIBColorCount(dibinfo.bmiHeader);
int nTotalSize = nInfoSize + GetDIBPixelSize(dibinfo.bmiHeader);

BYTE * pDIB = new BYTE[nTotalSize];

if ( pDIB )
{
memcpy(pDIB, & dibinfo, nInfoSize);

if ( ddbinfo.bmHeight != GetDIBits(hDC, hBmp, 0, ddbinfo.bmHeight, pDIB + nInfoSize, (BITMAPINFO *) pDIB, DIB_RGB_COLORS) )
{
delete [] pDIB;
pDIB = NULL;
}
}

if ( hpalOld )
SelectObject(hDC, hpalOld);

ReleaseDC(NULL, hDC);

return (BITMAPINFO *) pDIB;
}

BOOL SaveDIBToBmp(const char* pFileName, const BITMAPINFO *pBMI, const BYTE *pBits)
{
if(pFileName==NULL){
return FALSE;
}

HANDLE handle = CreateFile(pFileName, GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

if(handle == INVALID_HANDLE_VALUE){
return FALSE;
}

BITMAPFILEHEADER bmFH;

int nHeadSize = sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * GetDIBColorCount(pBMI->bmiHeader);

bmFH.bfType = 0x4D42;
bmFH.bfSize = nHeadSize + GetDIBPixelSize(pBMI->bmiHeader);
bmFH.bfReserved1 = 0;
bmFH.bfReserved2 = 0;
bmFH.bfOffBits = nHeadSize + sizeof(BITMAPFILEHEADER);

DWORD dwRead = 0;
WriteFile(handle, & bmFH, sizeof(bmFH), & dwRead, NULL);

if(pBits==NULL) // packed DIB
pBits = (BYTE *) pBMI + nHeadSize;

WriteFile(handle, pBMI, nHeadSize, & dwRead, NULL);
WriteFile(handle, pBits, GetDIBPixelSize(pBMI->bmiHeader), & dwRead, NULL);

CloseHandle(handle);

return TRUE;
}

给下面函数nBitCount 传递8表示保存为256色位图
BITMAPINFO * BitmapToDIB(HPALETTE hPal, // palette for color conversion
HBITMAP hBmp, // DDB for convert
int nBitCount, int nCompression) // format wanted

syh_17 2002-09-24
  • 打赏
  • 举报
回复
使用小畫家,在另存為是選擇存為256色即可

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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