请教CreateDIBSection怎么用?

du51 2009-02-08 11:03:09
谢谢各位了.
...全文
4234 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
shelly456 2010-08-21
  • 打赏
  • 举报
回复
谢谢 。。。。。。。。。。。。。。。。
zogna 2010-07-05
  • 打赏
  • 举报
回复
看帖。。
cnzdgs 2009-02-09
  • 打赏
  • 举报
回复
你应该用SetDIBitsToDevice。
实达诚实 2009-02-09
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 cnzdgs 的回复:]
你应该用SetDIBitsToDevice。
[/Quote]

  函数功能:该函数使用DIB位图和颜色数据对与目标设备环境相关的设备上的指定矩形中的像素进行设置。对于Windows 98和Windows NT 5.0,函数SetDIBitsToDevice已经得到扩展,它允许JPEG图像作为源图像。
  函数原型:int SetDIBitsToDevice(HDC hdc, int xDest, int Ydest, DWORD dwWidth, DWORD dwHeight, intXSrc, int Ysrc, UINT uStartScan, UINT cScanLines, CONST VOID *lpvBits, CONST BITMAPINFO *lpbmi, UINT fuColorUse);
  参数:
  hdc:设备环境句柄。
  XDest:指定目标矩形左上角的X轴坐标,按逻辑单位表示坐标。
  YDest:指字目标矩形左上角的Y轴坐标,按逻辑单位表示坐标。
  dwWidth:指定DIB的宽度,按逻辑单位表示宽度。
  dwHeight:指定DIB的高度,按逻辑单位表示高度。
  XSrc:指定DIB位图左下角的X轴坐标,按逻辑单位表示坐标。
  YSrc:指定DIB位图左下角的Y轴坐标,按逻辑单位表示坐标。
  uScanLines:指定DIB中的起始扫描线。
  cScanLInes:指定参数lpvBits指向的数组中包含的DIB扫描线数目。
  lpvBits:指向存储DIB颜色数据的字节类型数组的指针。关于更多的信息,请参考下面的备注一节。
  lpbmi:指向BITMAPINFO结构的指针,该结构包含有关DIB的信息。
  fuColorUse:指向BITMAPINFO结构中的成员bmiColors是否包含明确的RGB值或对调色板进行索引的值。有关更多的信息,请参考下面的备注部分。
  参数fuColorUse必须是下列值之一,这些值的含义如下:
  DIB_PAL_COLORS:表示颜色表由16位的索引值数组组成,利用这些值可对当前选中的逻辑调色板进行索引。
  DIB_RGB_COLORS:表示颜色表包含原义的RGB值。
  返回值:如果函数执行成功,那么返回值是设置的扫描线数目;如果函数失败,那么返回值为0。
  Windows NT:若想获得更多错误信息,请调用GetLastError函数。
  Windows 98、NT 5.0及以后版本:如果驱动程序不支持传给SetDIBitsToDevice函数的JPEG文件图像,那么函数将失败,并返回GDI_ERROR。
  备注:当位图的位是对系统调色板进行索引时,可获得最佳的位图绘制速度。应用程序可以通过调用GetSystemPaletteEntries函数来检索系统调色板的颜色和索引值。在检索到颜色和索引值之后,应用程序可以创建DIB。有关系统调色板方面更多的信息,请参考颜色方面的内容。
  自底向上的DIB位图的起始点是在该位图的左下角,而自顶向下的DIB的起始点是在左上角。
  为了减少对大型DIB位图的位进行设置所需的内存量,应用程序可以通过重复调用SetDIBitsToBevice。每次将位图的不同部分放入到lpvBits数组来将输出捆绑在一起。参数uStartScan和cScanLines的值标明了lpvBits数组中包含的位图部分。在有一个全屏幕MS DOS会话在前台运行时,如果正在后台运行的一个进程调用了SetDIBitsToDevice函数,那么该函数会返回一个错误。
  对于Windows 98、Windows NT 5.0及以后版本;如果BITMAPINFOHEADER中的成员biCompression为BI_JPEG,那么lpvBits指向一个包含JPEG图像的缓冲区。BITMAPINFOHEADER结构中的成员biSizeimage指定了该缓冲区的大小。参数fuColorUse必须设置为DIB_RGB_COLORS。如果BITMAPV4HEADER中的成员bV4SizeImage指定了该缓冲区的大小。参数fuColorUse必须设为DIB_RGB-COLORS。如果BITMAPV5HEADER结构中的成员bV5Compression为BI_JPEG,那么参数lpbBits指向一个包含JPEG图像的缓冲区。DITMAPV5HEADER结构中的成员bV5SizeImage指定了该缓冲区的大小,参数fuColorUse必须设为DIB_RGB_COLORS。
  ICM:进行颜色管理操作。如果指定的BITMAPINFO结构不是BITMAPV4HEADER或BITMAPV5HEADER,那么当前设备环境的颜色配置(profile)就当作源颜色配置使用。如果BITMAPINFO结构不是BITMAPV4HEADER或BITMAPV5HEADER,那么使用RGB颜色。如果指定的BITMAPINFO结构为BITMAPV4HEADER或BITMAPV5HEADER,那么与该位图有关的颜色配置(profile)就用作源颜色。
du51 2009-02-09
  • 打赏
  • 举报
回复
谢谢各位了.

祝 各位节日快乐,万事如意!
byxdaz 2009-02-09
  • 打赏
  • 举报
回复
这里面有相关介绍
http://www.vczx.com/article/show.php?id=218
cnzdgs 2009-02-09
  • 打赏
  • 举报
回复
根据你的上个帖子,这样处理更简便一些:
if (loadimage(_T("ClockBackchain.png"), &lpData, &nSize, &nHeight, &nWidth, &nPitch))
{
BITMAPINFOHEADER bih;
memset(&bih, 0, sizeof(bih));
bih.biSize = sizeof(bih);
bih.biWidth = nWidth;
bih.biHeight = nHeight;
bih.biPlanes = 1;
bih.biBitCount = 24;
bih.biSizeImage = nSize;
SetDIBitsToDevice(pDC->m_hDC, 0, 0, nWidth, nHeight, 0, 0, 0, nHeight, lpData, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
free(lpData);
}
「已注销」 2009-02-08
  • 打赏
  • 举报
回复
更正一下:
1)DeviceInfo.displaybuf = (ARGB8*)malloc(DeviceInfo.width * DeviceInfo.height * sizeof(ARGB8));
并不必须,因为我使用的是双Buffer
2)// 直接在您自己的DeviceInfo.displaybuf上执行绘制
同理:可以直接绘制在Step1建立的framebuf;

更正一下,以免误导楼主
Soyokaze 2009-02-08
  • 打赏
  • 举报
回复
调用完后,pBits是Windows已经分配好的像素内存块指针,直接用内存拷贝函数把已经读取好的像素阵列拷过去就行了。
CreateDIBSection返回一个位图句柄,可以选入DC场景进行GDI绘图操作,像素数据做相应改变。
laviewpbt 2009-02-08
  • 打赏
  • 举报
回复
CreateDIBSection 很好的一个函数,创建后,可以得到创建的图像在内存中的首地址,在VB中就可以利用模拟指针了,在VC中也就可以直接访问图像内存地址了。
「已注销」 2009-02-08
  • 打赏
  • 举报
回复
// Step 1:创建DIBSection
BITMAPINFO info;
memset(&info.bmiHeader, 0, sizeof(BITMAPINFOHEADER));
info.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
info.bmiHeader.biWidth = DeviceInfo.width;
info.bmiHeader.biHeight = DeviceInfo.height;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biBitCount = 32;
info.bmiHeader.biCompression = BI_RGB;

DeviceInfo.hBitmap = CreateDIBSection( NULL, (BITMAPINFO*) &info, DIB_RGB_COLORS, (void**) &DeviceInfo.framebuf, 0, 0);
DeviceInfo.displaybuf = (ARGB8*)malloc(DeviceInfo.width * DeviceInfo.height * sizeof(ARGB8));

// Step 2:绘制程序
// 直接在您自己的DeviceInfo.displaybuf上执行绘制
for(y = 0 ; ....)
for(x= 0; ....)

// Step 3:将绘制好的图形直接显示到设备上去
HDC hdc = GetDC(DeviceInfo.m_hWnd);

HDC mdc = CreateCompatibleDC( hdc );

HBITMAP hbmOld = (HBITMAP)::SelectObject(mdc, DeviceInfo.hBitmap);

BitBlt( hdc, 0, 0, DeviceInfo.width, DeviceInfo.height,
mdc, 0, 0, SRCCOPY);

::SelectObject(mdc, hbmOld);
DeleteDC(mdc);

ReleaseDC(DeviceInfo.m_hWnd, hdc);


说明:1)以上程序仅仅是示意程序;
2)不擅长MFC(从Windows 3.0开始编程的),所以全部程序用的是API
3)过程没有问题,我的gingkoVG的Windows版本就是这样输出的
Soyokaze 2009-02-08
  • 打赏
  • 举报
回复
呵呵,粗心了,这句
PVOIL pBits = NULL;
应该改成
PVOID pBits = NULL;
Soyokaze 2009-02-08
  • 打赏
  • 举报
回复
刚在原贴回复,转过来吧:

一个用CreateDIBSection创建32*32的32位位图的代码段

DWORD nWidth = 32;
DWORD nHeight = 32;
PVOIL pBits = NULL;
BITMAPINFO bi;
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = nWidth;
bi.bmiHeader.biHeight = nHeight;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = nHeight * nWidth * 4;
CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, &pBits, NULL, NULL);



每行是4字节对齐的,32位的比较简单,对于其它色深,通用公式(设置biSizeImage):
BytesPerScanLine = 4 * ((nWidth * nBitCount + 31) / 32)

19,468

社区成员

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

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