分享
 
 
 

在VC5中显示256色位图

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

在VC5中显示256色位图

李欣 周学泳

---- 在Windows的编程中,彩色图像的显示和处理一直是一个重要的课题,即使是在显卡普遍支持真彩的今天,讨论256色位图的显示也是有意义的。通过对这一课题的讨论,可以了解如何在VC5中实现装入图像,创建和使用调色板,以及最后将图像画出来。

---- 总的来说,要显示一幅256色的位图,首先应得到该图的有关信息,通过位图的颜色表创建一个逻辑调色板,然后将这个调色板选入设备环境,实现这个调色板,最后将位图用BitBlt函数拷贝到设备环境就可以了。

---- 具体实现步骤如下:

---- 1、装载位图并创建调色板。

---- 首先装入一幅位图,该位图既可以以资源的形式与程序绑在一起,也可以以文件的形式从外部装入。然后将该位图与一个Cbitmap对象联系(Attach)起来。在这儿我们应使用API函数LoadImage(),而不是CBitmap类的成员函数CBitmap::LoadBitmap(),因为我们需要得到该位图的DIBSECTION结构,从这个结构中我们可以得到该位图的色彩信息,从而建立一个与这些色彩相匹配的逻辑调色板。使用CBitmap::LoadBitmap()将会失去我们所需的位图的色彩信息。

---- 得到位图后,下一步工作就是取得该位图的色彩信息。通过CBitmap:GetObject()函数,我们可以访问DIBSECTION结构,从中得到位图的色彩数。一般来说,这些信息存在于BITMAPINFOHEAD结构中,不过,作为DIBSECTION结构的一部分,BITMAPINFOHEAD有时并未说明图像用了多少种颜色;碰到这种情况,我们可以看看图像的每一象素用了几位(Bit)来描述颜色,如果是8位的话,因为8位二进制数可以表示256种不同的值,所以该图像是256色的;同理,16Bit表明是64K色。得到了位图所用的颜色数,就可以创建逻辑调色板了。色彩超过256色的位图是没有颜色表(Color Table)的,这时我们只用简单地创建一个和设备环境兼容的半色调调色板(Halftone Palette)就行了,在半色调调色板中包含着所有不同颜色的样本。这显然不是最佳解决方案,但却是最简单的。

---- 而对于颜色数小于或等于256的位图,我们就要从头建立一个新的调色板。先分配足够的内存空间来装入图像的颜色表,颜色表可以利用API函数GetDIBColorTable获得;然后再分配足够的内存给新建的逻辑调色板,将刚才得到的颜色表信息相应拷入新建调色板中的palPalEntry域,并将PalVersion域设为0X300。创建了调色板后,应将窗口刷新重画。在具体的实现上,我们定义了一个函数GetBitmapandPalette()来实现位图资源的装入和逻辑调色板的创建,其功能实现框图如下(略)

---- 函数具体实现如下:

BOOL GetBitmapandPalette(LPCTSTR lpszresource,

CBitmap &bitmap, CPalette &pal,long *w,long *h)

{

LPCTSTR lpszresourcename = (LPCTSTR)lpszresource;

HBITMAP hbmp = (HBITMAP)::LoadImage( AfxGetInstanceHandle(),

lpszresourcename,IMAGE_BITMAP,0,0,

LR_LOADFROMFILE); //装入位图

if( hbmp == NULL )

return FALSE;

bitmap.Attach( hbmp );

// 将该位图与一个CBitmap对象联系起来

DIBSECTION ds;

BITMAPINFOHEADER &bminfo = ds.dsBmih;

bitmap.GetObject( sizeof(ds), &ds );

// 得到位图颜色数

int ncolors = bminfo.biClrUsed ?

bminfo.biClrUsed : 1 << bminfo.biBitCount; *w="bminfo.biWidth;" //得到位图宽度值 *h="bminfo.biHeight;" //得到位图高度值 CClientDC dc(NULL); // 创建逻辑调色板 if( ncolors> 256 )

pal.CreateHalftonePalette( &dc );

else

{

// 颜色数 <= 256 RGBQUAD *prgb="new" RGBQUAD[ncolors]; CDC memdc; memdc.CreateCompatibleDC(&dc); memdc.SelectObject( &bitmap ); ::GetDIBColorTable( memdc, 0, ncolors, prgb ); UINT nsize="sizeof(LOGPALETTE)" + (sizeof(PALETTEENTRY) * ncolors); LOGPALETTE *plp="(LOGPALETTE" *) new byte[nsize]; plp->palVersion = 0x300;

plp- >palNumEntries = ncolors;

for( int i=0; ipalPalEntry[i].peRed = prgb[i].rgbRed;

plp- >palPalEntry[i].peGreen = prgb[i].rgbGreen;

plp- >palPalEntry[i].peBlue = prgb[i].rgbBlue;

plp- >palPalEntry[i].peFlags = 0;

}

pal.CreatePalette( plp );

delete[] plp;

delete[] prgb;

}

return TRUE;

}

2.显示位图

在WM_PAINT消息的响应函数OnPaint()中实现。

void OnPaint()

{

CPaintDC dc(this); // device context for painting

// create a memory dc compatible with the paint dc

CDC memdc;

memdc.CreateCompatibleDC( &dc );

CBitmap bitmap;

CPalette palette;

long nWidth;

long nHeight;

//调用该函数

GetBitmapandPalette("e:\\project\ showimage\\bitmap1.bmp",bitmap,palette ,

&nWidth,&nHeight);

memdc.SelectObject( &bitmap );

// select and realize the palette

if( dc.GetDeviceCaps(RASTERCAPS) &

RC_PALETTE && palette.m_hObject != NULL )

{

dc.SelectPalette( &palette, FALSE );

dc.RealizePalette();

}

//显示位图

dc.BitBlt(0, 0, nWidth,nHeight, &memdc, 0, 0,SRCCOPY);

}

---- 以上程序只是简单的从一个固定路径(e:\\project\\showimage\\bitmap1.bmp)装入位图,读者可以将其功能扩充,如通过对话框选取等等,在此不多赘述。

---- 最后还要补充的一点是,如果要显示的位图是作为位图资源与程序联系在一起的,对以上程序稍作修改即可显示出来,修改方法如下:

首先将GetBitmapandPalette()函数改为:

BOOL GetBitmapandPalette(UINT nidresource,

CBitmap &bitmap, CPalette &pal,long *w,long *h)

其中nidresource是该位图的ID。

然后将GetBitmapandPalette()中的第一句改为:

LPCTSTR lpszresourcename = (LPCTSTR)nidresource;

并将LoadImage函数改为:

HBITMAP hbmp = (HBITMAP)::LoadImage( AfxGetInstanceHandle(),

nidresourcename,IMAGE_BITMAP,0,0,

LR_CREATEDIBSECTION);

最后,在OnPaint函数中调用GetBitmapandPalette()时,

将位图的ID

通过nidresource传入即可。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有