现在的位置: 首页 > 综合 > 正文

CreateDIBSection 与 CreateDIBITmap 的区别——详细探讨

2013年05月21日 ⁄ 综合 ⁄ 共 5877字 ⁄ 字号 评论关闭

CreateDIBSection 与 CreateDIBIT
map 的区别——详细探讨

[已结帖,结帖人:wonaixiaogang]

 

.
[华 软 网]

编程论坛
  楼主
很多人说,IDB和DDB之间的相互转换比较慢,所以我们使用CreateDIBSection()来创建一个DIB区块。这样作图速度快。
CreateDIBSection()返回的是一个HBITMAP,CreateDIBitmap()返回的也是HBIT
MAP。
两者的区别是,CreateDIBSection创建的是一个DIBSECTION结构,而CreateDIBitmap创建的是BIT
MAP结构。
----------------------------------------------------
DIB区块(DIBSECTION)是什么?看看它的结构:
typedef struct tagDIBSECTION {
  BIT
MAP              dsBm;
  BIT
MAPINFOHEADER    dsBmih;
  DWORD              dsBIT
fields[3];
  HANDLE              dshSection;
  DWORD              dsOffset;
} DIBSECTION, *PDIBSECTION;
可以看到,它包含了一个 位图结构BITMAP,一个DIB信息头BITMAPINFOHEADER,一个掩码表dsBIT
fields[3].
还有一个内存映射文件句柄和偏移量。我们不去理睬最后两个字段。
因此,使用GDI函数对CreateDIBSection()返回的HBIT
MAP作图是没有什么问题的。
-------------------------------------------------------------------------
我不明白的是,既然我们可以使用CreateDIBIT
map()来从DIB得到DDB,干嘛微软还要多此一举弄一个CreateDIBSection()(除开内存映射文件功能)?
这连个函数的作图效率有差别么?如果有,是什么原因。在我看来,DIB和DDB的区别无非就是信息头不同。一个是BITMAPINFOHEADER,一个是BIT
MAP,还有,一个带有颜色表,而另一个没有颜色表。而DIB和DDB的位图数据是完全一样的。

求牛人指教。

 

 

.
[华 软 网]

编程论坛
 1
 个网友回答:
CreateDIBitmap The DDB that is created will be whatever bIT
depth your reference DC is.
CreateDIBSection To create a bitmap that is of different bIT
depth 
 

.
[华 软 网]

编程论坛
 2
 
个网友回答:

你首先要搞明白DIB和DDB的区别,对于DDB到DIB的转换,只要加上一个位图信息头就是了;但是从DIB到DDB的转换,要根据当前DC的位图格式
(多少位色彩),可能要扩展也可能要减少色彩位数,如果你考虑这个因素,可以认为是由速度的损失。因此GDI下DDB作图肯定是最快的,直接拷贝位图数据
到显存即可。 
 

.
[华 软 网]

编程论坛
 3
 个网友回答:
该回复于2009-05-11 10:13:11被版主删除 
 

.
[华 软 网]

编程论坛
 4
 个网友回答:
其实一句话,使用CreateDIBSection()容易控制,因为你构造的BITMAPINFO是多少bit就按多少bIT
来操作它的位数据.
而CreateDIBitmap(), create出来的是DDB,是和屏幕色深相同的,在这台机它可能是16Bit的,而在那台机器它可能是24bit或者是32bIT
,明显不利于代码操控/维护..

CreateDIBSection()使用时传入一个LPB
IT
MAPINFO和一个空的CONST VOID **的指针,一旦create了,就可以直接对那个位数据指针(CONST VOID **)操纵,而不需要理会它是怎样转换为DDB的.

不过要说的是,DIB肯定比DDB慢,因为它还要转成DDB显示.
=====================================================
hBitmap = CreateDIBSection( hDC, ( CONST BIT
MAPINFO * )lPB
minfo, DIB_RGB_COLORS,
                        ( VOID ** )&PB
IT
s, NULL, 0 );

// 一旦create了,就可以直接操控PB
IT
s这个指针,例如:

memset( PB
IT
s, 0x0, ImageSize ); // 全部变黑或者象下面的
*( PB
IT
s + xxxx ) = 255;  // 对某个像素赋值.

========================================================
比较方便,所以很多人都会用这个方法,而且保存为文件时也是相当容易的,有BITMAPINFO和位数据指针,填个BIT
MAPFILEHEADER就可以全部写入为一个BMP了. 
 

.
[华 软 网]

编程论坛
 5
 个网友回答:
4楼,按你说法,我这样理解你看对不对:
当第四个参数是 DIB_RGB_COLORS时,CreateDIBSection()创建的DIB不使用HDC的色深,是和HDC不兼容的。那么我们直接使用CreateDIBSection()返回的HBIT
MAP 作图的时候,就有可能失败或者错误。
而当第四个参数是 DIB_PAL_COLORS 时,位图色深与HDC兼容,这时,我们用lPB
minfo指定的色深就无效了。此时就不能把DIB直接保存到文件中了。
如果我理解错误,请你解释一下,但DC和lPB
minfo的色深不一样时,CreateDIBSection()是如何工作的。谢谢 
 

.
[华 软 网]

编程论坛
 6
 个网友回答:
永远指定为DIB_RGB_COLORS,无论任何情况都不会作图失败的.
因为任何对该HBIT
MAP( DDB )的改动,都会反映在它的数据块内(那个const void ** 指针).

例如你用这个CreateDIBSection()函数建了个HBIT
AMP,就可以直接选入内存DC画图,然后就直接可以保存,因为所有改动都记录在数据指针内 :
HDC hDC = GetDC( NULL );
HBITMAP hBitmap = CreateDIBSection( hDC, ( CONST BIT
MAPINFO * )lPB
minfo, DIB_RGB_COLORS,
                        ( CONST VOID ** )&PB
IT
s, NULL, 0 );

HDC hMemDC = CreateCompatibleDC( hDC );

HBITMAP hOldBmp = ( HBITMAP )SelectObject( hMemDC, hBIT
map );
DrawCodeHere().....
DrawAgain().....
// releASE

SelectObject( hMemDC, hOldBmp );
DeleteDC( hMemDC );
ReleASE
DC( NULL, hDC );
// 然后就可以保存或者其它..
BIT
MAPFILEHEADER bmfh;
bmfh.bfType = 0x4d42;
.........
.....
..
==========================================================================
那是绝对和设备无关的, 绝对不会因为和设备不同而失败, 所以几乎都用它来构造什么CDib之类的.

当然,如果处理的是8bIT
或以下的bmp的话,还要有设置调色板( PALETTE )和彩色表( colors table )的代码 
 

.
[华 软 网]

编程论坛
 7
 个网友回答:
晕菜了。
DDB 究竟是什么样的结构?除了一个BIT
MAP信息头之外,是不是就只有数据区了?
数据区是什么格式的?是4字节一像素的RGB格式,还是每个像素指向DC的颜色表的索引值?
如果DDB的数据是32位1像素的RGB格式的,而DC是8位的256色的颜色盘。把DDB选入DC时,会进行数据区域的转换么?
如果不转换,用DC来作图岂不是会造成颜色错误? 
 

.
[华 软 网]

编程论坛
 8
 个网友回答:

引用 7 楼 wonaixiaogang 的回复:

晕菜了。
DDB 究竟是什么样的结构?除了一个BIT
MAP信息头之外,是不是就只有数据区了?
数据区是什么格式的?是4字节一像素的RGB格式,还是每个像素指向DC的颜色表的索引值?
如果DDB的数据是32位1像素的RGB格式的,而DC是8位的256色的颜色盘。把DDB选入DC时,会进行数据区域的转换么?
如果不转换,用DC来作图岂不是会造成颜色错误?

DDB很简单,你的系统是什么色深的,它就是什么色深.
你的系统设置是24Bit true color,DDB就是24Bit true color,如果设置的是16 or 32bit,那么DDB就是16 or 32BIT
.
根本就不会存在有32位DDB而DC是8位的.
DC就好比你的屏幕,而DDB就象是屏幕上显示的图,屏幕上能显示的图是多少位(色深),DDB就是多少位的.
DDB是设备相关的. 
 

.
[华 软 网]

编程论坛
 9
 个网友回答:

引用 8 楼 lambochan 的回复:

根本就不会存在有32位DDB而DC是8位的.

你这样说,那我们使用DC还有什么用?
屏幕和打印机的DC是不一样的,创建兼容位图就是说创建和DC兼容的位图,是要传入DC参数的。
DC绝对是有8位的,DDB也绝对是有32位的,就看你传入的DC是什么位。
为什么GDI的很多函数都要用到HDC传进参数?就是因为DC可能不一样。
在网上看了一下,CreateDIBSection()的第3个参数使用DIB_RGB_COLORS时,
CreateDIBSection()创建的DIB是直接由4字节一像素的RGB值构成,不使用HDC的色深,是和HDC不兼容的。
 
 

.
[华 软 网]

编程论坛
 10
 个网友回答:
当然,我可能说错了,也有可能,CreateDIBSection()的第3个参数使用DIB_RGB_COLORS时,
CreateDIBSection()创建的DIB是直接和屏幕的DC兼容,也就是使用系统的色深,
不过就算这样,依然是不使用传入的HDC的色深,是可能和HDC不兼容的。 
 

.
[华 软 网]

编程论坛
 11
 个网友回答:
晕..DC当然有8位,那是因为是设备是8位..
同样,DDB当然也有32位的.

很简单,use CreateCompaibleBitmap() Create个BIT
map出来,然后GetObject(),就知道设备是多少位的,因为Create出来的DDB是设备相关的.

同一台机器,DC绝对一样的.

"CreateDIBSection()创建的DIB是直接由4字节一像素的RGB值构成,不使用HDC的色深,是和HDC不兼容的。"
当然不是啦,create 8位的BMP的话,取它的DIB数据指针处理,每个像素还是一个字节的,24位就3个字节.
除非你是在32位色深系统下用GetObject()来取它HIBMTAP那个BIT
MAP结构里的DDB数据指针,那才会是4个字节的RGBX数据.

建议lz去看看周长发的 < <精通Visual C++
.NET
图象处理编程
>>.或者去google search DDB & DIB和DC的概念 
 

.
[华 软 网]

编程论坛
 12
 个网友回答:

引用 11 楼 lambochan 的回复:

同一台机器,DC绝对一样的.

你总是说一些片面的句子。
同一台机器,我自己创建的DC和屏幕DC就可能不一样。

引用 11 楼 lambochan 的回复:

当然不是啦,create 8位的BMP的话,取它的DIB数据指针处理,每个像素还是一个字节的,24位就3个字节.
除非你是在32位色深系统下用GetObject()来取它HIBMTAP那个BIT
MAP结构里的DDB数据指针,那才会是4个字节的RGBX数据.

你是说:CreateDIBSection()创建的DIB数据返回的指针 和GetObject()来取它HIBMTAP那个BIT
MAP结构里的DDB数据指针指向的不是同一个位置?
我去试验了下,证明这两个指针指向的是同一个位置。
 
 

.
[华 软 网]

编程论坛
 13
 个网友回答:
实验代码:

C/C++
code

void *ppV;
void *ppV2;
BITMAP B;
HBITMAP hBitmap = CreateDIBSection(NULL,(BIT MAPINFO *)PB uf,DIB_RGB_COLORS,&ppV,NULL,NULL);
GetObject( hBitmap, sizeof(BITMAP),&B);
ppV2 = B.bmBIT s ;
if(ppV==ppV2)
{
TRACE("相同/n");
}
else
{
TRACE("不同/n");
}

 
 

.
[华 软 网]

编程论坛
 14
 个网友回答:
现在我貌似有点点明白了:

CreateDIBSection()的第一个参数HDC和第二个参数BIT
MAPINFO的色深必须一样,使用DIB_PAL_COLORS时,函数才会成功。这是因为:

使用DIB_PAL_COLORS时,只是把HDC的颜色表拷贝到DIB的DIBSECTION里的颜色表。而使用DIB_RGB_COLOR时,
DIB的颜色表保持默认的颜色表。

也不知道我说对了没有。我靠,这函数网上的资料和MSDN都没说清楚。而使用它的人也都似懂非懂,将就使用。 
 

.
[华 软 网]

编程论坛
 15
 个网友回答:
那正好说明CreateDIBSection()创建出来的DIB由里到外都是设备无关...虽然偶还以为它那个HBITMAP的BIT
MAP结构已经转换为DDB.
但那又怎样呢?并不如你所说:它的像素是由四个字节RGBX组成的.
依然是8位就1个字节(color table索引),16位就两个字节,是绝对设备无关的.
在上面怎么作图,都不会因为系统色深不同而改变,依然是8bit还是8bit,24bit还是24bIT
.

说说你的DC..既然你都是说你创建的DC了,和屏幕的不一样又怎样..
估计你说的是CreateDC(),偶也不知道你Create出什么DC来.
不过,最终显示到屏幕上的DDB的色深肯定和显示设备设置的色深一样.
 
 

.
[华 软 网]

编程论坛
 16
 个网友回答:
传统所说的DC,就是屏幕的设备上下文.
偶之说以说它是一样的,那是因为通常都是用GetDC()来获取DC来显示,获得的色深在一台机器上肯定是相同的..

抱歉!评论已关闭.