我现在在内存里面构建了一个完整的bmp,包括文件头,信息头,调色板,以及数据,我想把它显示出来,应该怎么写程序啊?
我看了好几个显示bmp的程序,都是用loadbitmap加载的啊,我不知道不从文件加载应该怎么得到位图句柄,更应该如何显示呢?
帮忙啊,急啊!
我看了好几个显示bmp的程序,都是用loadbitmap加载的啊,我不知道不从文件加载应该怎么得到位图句柄,更应该如何显示呢?
帮忙啊,急啊!
调试欢乐多
hbp = CreateDIBitmap(h_DC,
(BITMAPINFOHEADER *)binfo,
CBM_INIT,
(LPSTR)pDate,
(LPBITMAPINFO)binfo,
DIB_RGB_COLORS );
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;
BITMAPINFO的结构是这样的,为什么
BITMAPINFO bitmapinfo;
bitmapinfo.bmiColors = new RGBQUAD[3];
编译通不过?
说
E:\chuanqi\viewWil2\WHWilImageData.cpp(67) : error C2440: '=' : cannot convert from 'struct tagRGBQUAD *' to 'struct tagRGBQUAD [1]'
我要怎么才能指定多个调色板呢?
首先要计算调色版的大小
然后加上BITMAPINFOHEADER的大小
顺便再扩大20几个字节
申请一块内存(有的时候把图像数据段的也申请在一起也是可以的)
unsigned char *p=(unsigned char *)malloc(sizeof(BITMAPINFOHEADER)+platSize+....)
然后用(BITMAPINFOHEADER*)p->....这样可以把头填好
然后用(p+sizeof(BITMAPINFOHEADER))做指针填写调色板(创建好了,往里复制)
这样处理以后
(BITMAPINFO*)p,
你再看这个p是不是就符合tagBITMAPINFO 的定义了?
mfc中有CPalette这个类,可以创建调色板,你自己看看吧
比如256色的(就是8位的),可以知道最多一共有256种颜色色
比如数据段中存放有0xA1,x0xB5,x0FF这样的数据
256色用每个字节表示一个像素
0xA1,表示这个点得像素的颜色和调色板的第0xA1项是相同的
调色板的数据都是这样的(r,g,b,保留位(不用考虑))
这样我们就可以用一个8位字节描述一个真彩色的点了
当然,虽然失真彩色的,正张图片中的所有像素的色彩总和只有256中
因为通常一张bmp中所有得像素色彩不可能用到真彩的所有颜色,再加上很多情况下一些点是相近的(肉眼无法分辨),所以各种压缩才有意义
{
BITMAP bm; HBITMAP phBitmap = NULL;
phBitmap = (HBITMAP)LoadImage( hInst, szFileName, IMAGE_BITMAP, 0, 0,
LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
if( phBitmap == NULL )
return FALSE; GetObject(phBitmap, sizeof(BITMAP), &bm );
if( ( bm.bmBitsPixel * bm.bmPlanes ) <= 8 )
{
HDC hMemDC;
HBITMAP hOldBitmap;
hMemDC = CreateCompatibleDC( NULL );
hOldBitmap = (HBITMAP)SelectObject( hMemDC, phBitmap ); SelectObject( hMemDC, hOldBitmap );
DeleteDC( hMemDC );
}
else
{
HDC hRefDC; hRefDC = ::GetDC( NULL );
::ReleaseDC( NULL, hRefDC );
}
return phBitmap;
}
如果是16Bit的调色板位图,那好办了,位数据只是调色板的索引,把16Bit RGBQUAD转换为24BIT RGBQUAD并实现PALETTE,然后就可以直接显示了..TNND,16Bit是如下所保存的?
一个WORD:
0x0bbbbbgggggrrrrr <= 5位保存一个r、g、b值?
0bbbbbgggggrrrrr
看看这个有没有帮助
我也是来这里学习的!
另外我知道16位的掩码调色板是
bbbbbggggggrrrrr这种16位数据的掩码!
好象三个分别是
F8000000
007D0000
00001F00
HDC hdc, // handle to DC
CONST BITMAPINFO *pbmi, // bitmap data
UINT iUsage, // data type indicator
VOID **ppvBits, // bit values
HANDLE hSection, // handle to file mapping object
DWORD dwOffset // offset to bitmap bit values
);
then
StretchDIBits()
总要知道是从什么文件来的,
或者是从什么色的数据转化来的
或者是从哪个DC存下来的因为有人甚至通过改变调色板来改变图像效果,你说调色板靠得住么??
我曾经在把24位位图象256位图压缩的时候自己创建了一个调色板,愣给每个RGBQUAD付的值
不知道
http://www.vckbase.com/code/listcode.asp?mclsid=7&sclsid=703
这个试我以前做的例子,不过没有代码了,只有库,这里面的调色板就是手动创建的
调色板和数据可以得到显示效果SelectObject(..)
只有数据既不能得到调色板,也不能得到显示效果
自己构造BITMAPINFO~~
就是 lsaturn(土星-站了一晚) 说的
F8000000
007D0000
00001F00
是rgb的掩码,
akiy(winexec)你怎么能连续回复4次呢?星星的原因?
我整理下我的程序,大家来看看吧!
{
BITMAPFILEHEADER BitmapFilehead;
BITMAPINFOHEADER BitmapInfo;
RGBQUAD quadRGB[3];
WORD* pwEffectData;
}BITMAPDATA, *LPBITMAPDATA;
LPBITMAPDATA m_lpstFinalBitmap;m_lpstFinalBitmap->BitmapFilehead.bfType = ((WORD) ('M' << 8) | 'B'); // is always "BM"
m_lpstFinalBitmap->BitmapFilehead.bfSize = m_lpstNewCurrWilImageInfo->shWidth * m_lpstNewCurrWilImageInfo->shHeight * 2 + 0x42;
m_lpstFinalBitmap->BitmapFilehead.bfReserved1 = 0; //保留字
m_lpstFinalBitmap->BitmapFilehead.bfReserved2 = 0; //保留字
m_lpstFinalBitmap->BitmapFilehead.bfOffBits = 0x42;m_lpstFinalBitmap->BitmapInfo.biSize = sizeof(BITMAPINFOHEADER);
m_lpstFinalBitmap->BitmapInfo.biWidth = m_lpstNewCurrWilImageInfo->shWidth;
m_lpstFinalBitmap->BitmapInfo.biHeight = m_lpstNewCurrWilImageInfo->shHeight;
m_lpstFinalBitmap->BitmapInfo.biPlanes = 1;
m_lpstFinalBitmap->BitmapInfo.biBitCount = 16;
m_lpstFinalBitmap->BitmapInfo.biCompression =BI_BITFIELDS;
m_lpstFinalBitmap->BitmapInfo.biSizeImage = m_lpstNewCurrWilImageInfo->shWidth * m_lpstNewCurrWilImageInfo->shHeight * 2;
m_lpstFinalBitmap->BitmapInfo.biXPelsPerMeter = 0;
m_lpstFinalBitmap->BitmapInfo.biYPelsPerMeter = 0;
m_lpstFinalBitmap->BitmapInfo.biClrUsed = 0;
m_lpstFinalBitmap->BitmapInfo.biClrImportant =0;m_lpstFinalBitmap->quadRGB[0].rgbBlue = 0;
m_lpstFinalBitmap->quadRGB[0].rgbGreen = 0xF8;
m_lpstFinalBitmap->quadRGB[0].rgbRed = 0;
m_lpstFinalBitmap->quadRGB[0].rgbReserved = 0;
m_lpstFinalBitmap->quadRGB[1].rgbBlue = 0xE0;
m_lpstFinalBitmap->quadRGB[1].rgbGreen = 0x07;
m_lpstFinalBitmap->quadRGB[1].rgbRed = 0;
m_lpstFinalBitmap->quadRGB[1].rgbReserved = 0;
m_lpstFinalBitmap->quadRGB[2].rgbBlue = 0x1F;
m_lpstFinalBitmap->quadRGB[2].rgbGreen = 0;
m_lpstFinalBitmap->quadRGB[2].rgbRed = 0;
m_lpstFinalBitmap->quadRGB[2].rgbReserved = 0;m_lpstFinalBitmap->pwEffectData我已经给它赋上正确的值了,它指向有效的数据!上面的是对的,我受lsaturn(土星-站了一晚)的启发,把上面的一股脑写到一个bmp文件里面去显示出来的图象是正确的,但是直接在内存里面应该怎样使它显示呢?
然后
HBITMAP hbp;
hbp = CreateDIBitmap(h_DC,
(BITMAPINFOHEADER *)binfo,
CBM_INIT,
(LPSTR)pDate,
(LPBITMAPINFO)binfo,
DIB_RGB_COLORS );
再不行发给我
[email protected]
坛子里说这个得贴都没数了
[email protected]
==========================================================
typedef struct {
BITMAPINFOHEADER bmiHeader; //位图信息头
RGBQUAD bmiColors[3]; //颜色表
} BMINFO16BIT;//自己包装 CFile file;
if(!file.Open(str,CFile::modeRead))
{
AfxMessageBox("File cannot open..");
return;
}
BYTE a[256*192*2];
file.Read(a,256*192*2);
file.Close();
bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bminfo.bmiHeader.biWidth = 256;
bminfo.bmiHeader.biHeight = 192;
bminfo.bmiHeader.biPlanes = 1;
bminfo.bmiHeader.biBitCount = 16;
bminfo.bmiHeader.biCompression = BI_BITFIELDS;
bminfo.bmiHeader.biSizeImage = 256 * 192 * 2;
bminfo.bmiHeader.biXPelsPerMeter = 0;
bminfo.bmiHeader.biYPelsPerMeter = 0;
bminfo.bmiHeader.biClrUsed = 0;
bminfo.bmiHeader.biClrImportant =0; bminfo.bmiColors[0].rgbBlue = 0;
bminfo.bmiColors[0].rgbGreen = 0xF8;
bminfo.bmiColors[0].rgbRed = 0;
bminfo.bmiColors[0].rgbReserved = 0;
bminfo.bmiColors[1].rgbBlue = 0xE0;
bminfo.bmiColors[1].rgbGreen = 0x07;
bminfo.bmiColors[1].rgbRed = 0;
bminfo.bmiColors[1].rgbReserved = 0;
bminfo.bmiColors[2].rgbBlue = 0x1F;
bminfo.bmiColors[2].rgbGreen = 0;
bminfo.bmiColors[2].rgbRed = 0;
bminfo.bmiColors[2].rgbReserved = 0; CClientDC dc(this);
void *pBits;
HBITMAP hbitmap = CreateDIBSection(dc.m_hDC,
(const BITMAPINFO *)&bminfo,
DIB_RGB_COLORS,
(VOID **)&pBits,
NULL,
0); memcpy(pBits,a,256*192*2);
GdiFlush();
StretchDIBits(dc.m_hDC,0,0,bminfo.bmiHeader.biWidth,
bminfo.bmiHeader.biHeight,0,0,bminfo.bmiHeader.biWidth,
bminfo.bmiHeader.biHeight,pBits,(BITMAPINFO *)&bminfo,
DIB_RGB_COLORS,SRCCOPY);=============================================================================以上随便乱写的,可以显示row数据(为16bitbmp),bmp应该一样的吧
HDC hDC = GetDC(hWnd);
DrawDibDraw(hDrawDib,hDC,0,0,width,height,&(m_lpstFinalBitmap->BitmapInfo),m_lpstFinalBitmap->pwEffectData,0,0,width,height,DDF_HALFTONE);
ReleaseDC(hWnd,hDC);
DrawDibClose(hDrawDib);
必须包含<vfw.h>和winmm.lib,vfw32.lib
并非灌水呀~~
kaka..
Raw数据都行,没理由DIB不行的,TNND..
char* binfo;
binfo = (char*)malloc(sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD) +
sizeof(WORD) * m_pwImage->m_lpstNewCurrWilImageInfo->shWidth
* m_pwImage->m_lpstNewCurrWilImageInfo->shHeight);
memcpy(binfo, &m_pwImage->m_lpstFinalBitmap->BitmapInfo, sizeof(BITMAPINFOHEADER));
memcpy(binfo + sizeof(BITMAPINFOHEADER), m_pwImage->m_lpstFinalBitmap->quadRGB, 3 * sizeof(RGBQUAD));
memcpy(binfo + sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD), m_pwImage->m_lpstFinalBitmap->pwEffectData, sizeof(WORD) * m_pwImage->m_lpstNewCurrWilImageInfo->shWidth * m_pwImage->m_lpstNewCurrWilImageInfo->shHeight);
hBitmap = CreateDIBitmap(hSrcDC,
(BITMAPINFOHEADER *)binfo,
CBM_INIT,
(LPSTR)binfo,
(LPBITMAPINFO)binfo,
DIB_RGB_COLORS );
显示出来一团糟!
我把代码贴这,可能比较乱,sorry~~~
=================================================================================
void CMy16BitView::showDIB()
{
CMy16BitDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc); CString str;
str = pDoc->GetPathName();
CFile file;
if(!file.Open(str,CFile::modeRead))
{
AfxMessageBox("File cannot open..");
return;
}
BITMAPFILEHEADER bmfh;
file.Read(&bmfh,sizeof(BITMAPFILEHEADER));
BITMAPINFOHEADER bmih;
file.Read(&bmih,sizeof(BITMAPINFOHEADER));
DWORD m_BitLen = bmfh.bfSize - bmfh.bfOffBits;
DWORD FileOffset = file.GetPosition();
BYTE *Bits = (BYTE *)malloc(m_BitLen);
file.Seek(FileOffset+bmfh.bfOffBits,CFile::begin);
file.ReadHuge(Bits,m_BitLen);
//file.Close();
bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bminfo.bmiHeader.biWidth = bmih.biWidth;
bminfo.bmiHeader.biHeight = bmih.biHeight;
bminfo.bmiHeader.biPlanes = 1;
bminfo.bmiHeader.biBitCount = 16;
bminfo.bmiHeader.biCompression = BI_BITFIELDS;
bminfo.bmiHeader.biSizeImage = 0;//bmih.biWidth * bmih.biHeight * 2;
bminfo.bmiHeader.biXPelsPerMeter = 0;
bminfo.bmiHeader.biYPelsPerMeter = 0;
bminfo.bmiHeader.biClrUsed = 0;
bminfo.bmiHeader.biClrImportant =0; bminfo.bmiColors[0].rgbBlue = 0;
bminfo.bmiColors[0].rgbGreen = 0xF8;
bminfo.bmiColors[0].rgbRed = 0;
bminfo.bmiColors[0].rgbReserved = 0;
bminfo.bmiColors[1].rgbBlue = 0xE0;
bminfo.bmiColors[1].rgbGreen = 0x07;
bminfo.bmiColors[1].rgbRed = 0;
bminfo.bmiColors[1].rgbReserved = 0;
bminfo.bmiColors[2].rgbBlue = 0x1F;
bminfo.bmiColors[2].rgbGreen = 0;
bminfo.bmiColors[2].rgbRed = 0;
bminfo.bmiColors[2].rgbReserved = 0; CClientDC dc(this);
//void *pBits;
HBITMAP hbitmap = CreateDIBSection(dc.m_hDC,
(const BITMAPINFO *)&bminfo,
DIB_RGB_COLORS,
(VOID **)&pBits,
NULL,
0); memcpy(pBits,Bits,bmih.biWidth * bmih.biHeight * 2);
free(Bits);
GdiFlush();
StretchDIBits(dc.m_hDC,0,0,bminfo.bmiHeader.biWidth,
bminfo.bmiHeader.biHeight,0,0,bminfo.bmiHeader.biWidth,
bminfo.bmiHeader.biHeight,pBits,(BITMAPINFO *)&bminfo,
DIB_RGB_COLORS,SRCCOPY);
//AfxMessageBox("ok!");
}
在View中声明:
typedef struct {
BITMAPINFOHEADER bmiHeader; //位图信息头
RGBQUAD bmiColors[3]; //颜色表
} BMINFO16BIT;//自己包装
BMINFO16BIT bminfo;
void *pBits;========================================================
来试试~~改好点,偶临急临忙乱写的
还没找到哪错了.>_<
水饺先,kakaka
hbitmap = CreateDIBSection(dc.m_hDC,
(const BITMAPINFO *)&bminfo,
DIB_RGB_COLORS,
(VOID **)&pBits,
NULL,
0);
这个是在干什么啊?我一直比较疑惑BITMAPINFO就是多了一个RGBQUAD,这是干什么用的呢?
pBits这个是没有初始化的,你放进去干什么呢?我还以为你会用Bits而不是pBits啊!
函数返回之后pBits是什么啊?
这是不是把dib转为ddb呢?
上面那是为pBits分配内存,因为hSection句柄设为NULL..然后把数据Copy入pBits,hbitmap并不仅仅包含DDB句柄..你把bminfo适当地修改为你的图片的BITMAPINFOHEADER的数据,然后把你的位数据memcpy()
到pBits,就能显示的了
如果不设置这3个掩码,将得不到正确的色彩..
你试去掉这:
typedef struct {
BITMAPINFOHEADER bmiHeader; //位图信息头
//RGBQUAD bmiColors[3]; //3个DD
} BMINFO16BIT;//自己包装
和注释掉色彩表的附值实验一下就知道了..
有位图的详细介绍,包括16Bit.
(const BITMAPINFO *)&bminfo,
DIB_RGB_COLORS,
(VOID **)&pBits,
NULL,
0);解释清楚点:上面那个是根据bminfo创建了一张空白可写入数据的位图,然后就把数据倒向pBits,土星兄这次应该明了吧..该水饺了...
ZZZZZzzzzzzzzz.
{
if(*phDIB)
{
GlobalFree(*phDIB);
*phDIB = NULL;
}
if(*phBuf == NULL)
{
return FALSE;
} long nFileLen;
nFileLen = GlobalSize(*phBuf); HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nFileLen);
if(hDIB == NULL)
return FALSE; memcpy((LPSTR)hDIB, *phBuf, nFileLen - sizeof(BITMAPFILEHEADER)); BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB; int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :
1 << bmInfo.bmiHeader.biBitCount;
if(nColors <= 256)
{
//如果小于256色,就建立调色板
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; pLP->palVersion = 0x300;
pLP->palNumEntries = nColors; for(int i = 0; i < nColors; i++)
{
pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
pLP->palPalEntry[i].peFlags = 0;
} pPal->CreatePalette(pLP);
delete[] pLP;
}
*phDIB = hDIB;
return TRUE;
}
{
//位图指针
LPVOID lpDibBits;
BOOL bSuccess = FALSE; //取得位图说明
BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDib;
//判断颜色表是否不足
int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :
1 << bmInfo.bmiHeader.biBitCount; //得到色彩数
if(bmInfo.bmiHeader.biBitCount > 8) //如果是256色以上
{
lpDibBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors +
bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
}
else
{
lpDibBits = (LPVOID)(bmInfo.bmiColors + nColors);
}
//取得指向位图的数据指针
if(pPal && (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE))
{
pDC->SelectPalette(pPal, FALSE);
pDC->RealizePalette();
}
if(m_ShowMode == 2) //完整显示
{
::SetDIBitsToDevice(pDC->m_hDC, //hDC
0, //DestX
0, //DestY
bmInfo.bmiHeader.biWidth, //nDestWidth
bmInfo.bmiHeader.biHeight,//nDestHeight
0, //SrcX
0, //SrcY
0, //nStartScan
bmInfo.bmiHeader.biHeight,//nNumScans
lpDibBits, //lpBits
(LPBITMAPINFO)hDib, //lpBitsInfo
DIB_RGB_COLORS); //wUsage
}
else
{
CRect rect;
GetClientRect(&rect);
int height;//按原来的比例显示图像,这里没有考虑窗口被调整成扁平的情况
if(m_ShowMode == 0)
height = rect.Width()*bmInfo.bmiHeader.biHeight/bmInfo.bmiHeader.biWidth;
else if(m_ShowMode == 1)
height = rect.Height();
else
return;
::StretchDIBits(pDC->m_hDC,
0, (rect.Height() - height)/2, rect.Width(), height,
0, 0, bmInfo.bmiHeader.biWidth, bmInfo.bmiHeader.biHeight,
lpDibBits,
(LPBITMAPINFO)hDib,
DIB_RGB_COLORS,
SRCCOPY);
}
}
怎么你就知道水饺啊:)
http://www.fantasiasoft.net/Documents/BMPFormat.htm
这个文章我原来看过了,刚开始分析的时候就看的这个
主要是我觉得BITMAPINFO这个结构中的RGBQUAD[1]从你的程序看来是什么值无所谓啊,是不是这样的,具体怎么来使用RGBQUAD会根据bminfo.bmiHeader.biCompression的值来读取BITMAPINFOHEADER后面的值,是吗?
phBuf,原始的位图数据,开始是BITMAPINFO结构
phDIB,从phBuf中提取要显示的位图数据,就是下面函数的hDib
pPal, 建立的调色板
lambochan(打杂),我也想知道如下的问题:
主要是我觉得BITMAPINFO这个结构中的RGBQUAD[1]从你的程序看来是什么值无所谓啊,是不是这样的,具体怎么来使用RGBQUAD会根据bminfo.bmiHeader.biCompression的值来读取BITMAPINFOHEADER后面的值,是吗?
看大家这么帮我,我再给帖子加50分:)
其实biBitCount<=8时,才有调色板(色彩表)的,不过正如那篇BMP资料说的那样,16位色是最麻烦的,当bminfo.bmiHeader.biCompression =BI_RGB时,不需要设置调色板,像素值直接按(WORD)0bbbbbgggggrrrrr储存(15位32K色),当为
bminfo.bmiHeader.biCompression = BI_BITFIELDS时,色彩表位置被那3个DD占据,它并不是调色板,而是像素值的掩码,所以必须设置那3个bmiColors,不设置的话得不到正确的颜色..
具体我也是实验过才知道的,呵呵..
这么说来BITMAPINFO这个结构中的RGBQUAD[1]完全是多余的,随便填写什么值都可以了!
你可以去掉这3个DD,但颜色不正确。
你还可以试试把全它设成0,程序会崩溃。kaka.
RGBQUAD[1]不是表示只有1个数组,而是表示色彩表中只有1种颜色呀,如256色(8Bit,biBitCount = 8)时:RGBQUAD bmiColors[256] <===变成这样了,有256种色彩.
RGBQUAD其实就是调色板位图位数据的颜色索引,当根据这个色彩表实现了Palette,位图才能显示正确的颜色..调色板位图只有一个RGBQUAD数组,而biBitCount决定了这个色彩表的数组大小,并非是说:RGBQUAD bmiColors[2] == 两个调色板,这只是说这个色彩表里有两种颜色.
也就是告诉你实现Palette时,颜色只有两种..
通常,biBitCount>8时,没有色彩表的,但16Bit例外,16Bit位图的bminfo.bmiHeader.biCompression = BI_BITFIELDS时,色彩表为:RGBQUAD bmiColors[3],这并非是说有3个调色板,而是色彩表数组大小为3,本来色彩表储存着位图位数据的颜色值,但16Bit却不是,这3个DD只是位数据的颜色值的掩码,所以根本不需要实现Palette..不知你看明了没有,偶写得乱糟糟的,再写下去,可能把自己也弄糊涂了,呵呵~~
RGBQUAD不是什么值都无所谓的,它保存着"调色板位图"里位数据的颜色值,而位数据只是色彩表里所保存颜色的索引号.
OK~~又三帖了,汗ing
我确实混淆了调色板和色彩表,你这一说,我结合那个文章一看就清楚些了。
是不是在bitmapinfo中虽然定义的RGBQUAD bmiColors[1]但RGBQUAD结构到底有多少了数组,还是由BITMAPINFOHEADER中的相关项来决定长度的?
其实可以说RGBQUAD bmiColors[1]相当于一个占位的作用!
hbp = CreateDIBitmap(h_DC,
(BITMAPINFOHEADER *)binfo,
CBM_INIT,
(LPSTR)pDate,
(LPBITMAPINFO)binfo,
DIB_RGB_COLORS );
//或許有幫助???
lambochan(打杂)最后来一次嘛,
---------------------------------------------------------------------------
我确实混淆了调色板和色彩表,你这一说,我结合那个文章一看就清楚些了。
是不是在bitmapinfo中虽然定义的RGBQUAD bmiColors[1]但RGBQUAD结构到底有多少了数组,还是由BITMAPINFOHEADER中的相关项来决定长度的?
其实可以说RGBQUAD bmiColors[1]相当于一个占位的作用!
----------------------------------------------------------------
是不是占位的作用嘛,水饺水饺:)
水饺去了~~
有用的,不是占位..
你可以做个实验:举个256色图片位例:
typedef struct {
BITMAPINFOHEADER bmiHeader; //位图信息头
RGBQUAD bmiColors[256]; //现在256色了
} BMINFO256;//封装为256色.
BMINFO256 256bitmap;
用这个Load入BITMAPINFOHEADER和RGBQUAD.
当用CreatDIBSection()(用上面的(const BITMAPINFO *)&256bitmap)创建一幅8Bit的空白DIB,然后倒入位数据,实现Palette,把图象显示出来..
现在可以来试试了:
这个256bitmap.bmiColors读入了刚显示位图的色彩表,现在要它变换:
for(int i=0;i<16;++i)
{
256bitmap.bmiColors[i].rgbBlue = 256bitmap.bmiColors[i+16].rgbBlue;
256bitmap.bmiColors[i].rgbGreen = 256bitmap.bmiColors[i+16].rgbGreen;
256bitmap.bmiColors[i].rgbRed = 256bitmap.bmiColors[i+16].rgbRed;
256bitmap.bmiColors[i].rgbReserved = 256bitmap.bmiColors[i+16].rgbReserved;
}//把色彩表的前16种颜色改为和后面16种相同的颜色;
接着:
Invalidate();
UpdateWindow();//重新显示..注意,并没重新实现调色板..
现在,你可以看到图片变得古怪了..呵呵,因为色彩表的前16项颜色被改变了.可见,并不是在占位哟..
我想我基本明白了,这个RGBQUAD bmiColors[1]官方定义的是1长度的数组,但是因为数据实际上是连续储存的,究竟如何解释后面这些连续的数据,哪些是色彩表,哪些是有效数据还是由前面的BITMAPINFOHEADER来决定的。
因为色彩表长度的不固定,所以使我迷惑了。
楼上的,我说的对吧?
由BITMAPINFOHEADER的几个值域来决定的..置顶了吗?偶没留意啊,keke
我想我基本明白了,这个RGBQUAD bmiColors[1]官方定义的是1长度的数组,但是因为数据实际上是连续储存的,究竟如何解释后面这些连续的数据,哪些是色彩表,哪些是有效数据还是由前面的BITMAPINFOHEADER来决定的。
HDC tmphdc;
BITMAPINFO bitmapinfo;
void *bmpdata;
frontbit=CreateDIBSection(tmphdc,&bitmapinfo,DIB_RGB_COLORS,(VOID**)&bmpdata,NULL,0);为什么CreateDIBSection后bmpdata为NULL?
超出右界时,并不出现水平滚动条?