getdibits(C++函数GetDIBits怎么用)

2026-08-17 01:45:06 0

getdibits(C++函数GetDIBits怎么用)

各位老铁们,大家好,今天由我来为大家分享getdibits,以及C++函数GetDIBits怎么用的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们开始吧!

本文目录

C++函数GetDIBits怎么用

HBITMAP是常用的GDI对象,而GetDIBits可以从一个HBITMAP对象中获得其对应的位数据。
其原型如下:
int GetDIBits(    HDC hdc, // handle to DC 
hdc, // handle to DC 
                            HBITMAP hbmp, // handle to bitmap 
                            UINT hbmp, // handle to bitmap 
                            UINT uStartScan, // first scan line to set 
                            UINT cScanLines, // number of scan lines to copy 
                            LPVOID cScanLines, // number of scan lines to copy 
                            LPVOID lpvBits, // array for bitmap bits 
                            LPBITMAPINFO lpbi, // bitmap data buffer 
                            UINT lpbi, // bitmap data buffer 
                            UINT uUsage // RGB or palette index );

标准的GetDIBits调用方式是两次调用:
第一次传入空的 lpvBits,此时的lpbi作为传出参数,从中可以获得lpvBits所需的内存区域大小。
    BYTE *lpvBits = NULL;
    BITMAPINFO bmpInfo = {0};
    bmpInfo.bmiHeader.biSize = sizeof(bmpInfo.bmiHeader);

    /*    第一次调用GetDIBits获得bmpInfo    */
    nRet = ::GetDIBits(hDC, hBitmap, 0, pBmpData-》bmHeight, NULL, &bmpInfo, DIB_RGB_COLORS); 
    if (nRet == 0) {
        nRet = GetLastError();
        TRACE( _T("GetDIBits for bmpInfo failed %d/n"), nRet);
        goto err;
    }

以上调用如果成功,就会在bmpInfo.bmiHeader.biSizeImage记录位数据所占的内存区大小,
此时就可以动态分配内存,然后再次调用GetDIBits获得实际的位数据:

    lpvBits= new BYTE;
    if (NULL == pBitsBuffer) {
        nRet = -1;
        TRACE( _T("Allocate memory for lpvBits failed/n"));
        goto err;
    }

    /*    第二次调用GetDIBits获得位图数据    */
    nRet = ::GetDIBits(hDC, hBitmap, 0, pBmpData-》bmHeight, lpvBits, &bmpInfo, DIB_RGB_COLORS); 
    if (nRet == 0) {
        nRet = GetLastError();
        TRACE( _T("GetDIBits for lpvBits failed %d/n"), nRet);
        goto err;
    }

很多时候,因为位图的长宽和颜色深度都是已知的,因此位数据所占的内存区大小可以由公式
 width * heigth * pixelBits / 8 计算获得

那是否可以省略第一步调用呢?
答案是:最好不要

原因是 bmpInfo.bmiHeader.biSizeImage 并不一定等于 width * heigth * pixelBits / 8

经过多次测试发现,对于16位颜色深度的位图,如果其宽度为奇数,则第一次GetDIBits获得
的位数据大小为 (width+1) * heigth * pixelBits / 8

也就是说对于16位颜色深度的位图,HBITMAP对象对其进行存储时,自动将宽度调整为了偶
数,也即将每行数据对齐到4字节(一个DWORD的长度)。

暂时没有查到相关的解释,我的猜想是这是为了在进行像素操作时能直接以DWORD为单位,
这样比以WORD为单位能减少一半的操作次数。

////

16位操作系统下如果使用这种方法获得的将是16位图

biBitCount=16

表示位图最多有2^16种颜色。每个像素用16位(2个字节)表示。这种格式叫作高彩色,或叫增强型16位色,或64K色。它的情况比较复杂,当biCompression成员的值是BI_RGB时,它没有调色板。16位中,最低的5位表示蓝色分量,中间的5位表示绿色分量,高的5位表示红色分量,一共占用了15位,最高的一位保留,设为0。//-》备注1

这种格式也被称作555 16位位图。

内存分布如下

如果biCompression成员的值是BI_BITFIELDS,(const DWORD BI_BITFIELDS = 3;)那么情况就复杂了,首先是原来调色板的位置被三个DWORD变量占据,称为红、绿、蓝掩码。分别用于描述红、绿、蓝分量在16位中所占的位置。在Windows 95(或98)中,系统可接受两种格式的位域:555和565,在555格式下,红、绿、蓝的掩码分别是:0x7C00、0x03E0、0x001F,而在565格式下,它们则分别为:0xF800、0x07E0、0x001F。你在读取一个像素之后,可以分别用掩码“与”上像素值,

从而提取出想要的颜色分量(当然还要再经过适当的左右移操作)。在NT系统中,则没有格式限制,只不过要求掩码之间不能有重叠。(注:这种格式的图像使用起来是比较麻烦的,不过因为它的显示效果接近于真彩,而图像数据又比真彩图像小的多,所以,它更多的被用于游戏软件)。我们只需要读取其中的R或者G的掩码,来判断是那种格式。以红色掩码为例 0111110000000000的时候就是555格式 1111100000000000就是565格式。

555 格式 xrrrrrgggggbbbbb

565 格式 rrrrrggggggbbbbb

解析555格式的代码:

BYTE b= bmpData;

BYTE g=((bmpData》》5);

BYTE r=(bmpData《《1)》》3;

有一点值得提醒的是由于有较多的位操作,所以在处理的时候在前一次操作的上面加上一对括号。

现在我们得到了55RGB各自的分量,但是还有一个新的问题,那就是由于两字节表示了3个颜色  555下每个颜色最多到0x1F。所以我们需要一个转换,这就是掩码的用武之地,将得到的各颜色分量和相应的掩码做与运算,或者乘8就可以了,推荐用与运算。

以下是565格式时的数据分离:

BYTE b= bmpData;

BYTE g=((bmpData》》5);

BYTE r=bmpData》》3;

现在我们得到了565RGB各自的分量,但是仍然还有一个新的问题,565格式下最大的绿色分量也就0x3F。所以我们需要一个转换,这就是掩码的用武之地,将各颜色分量和相应的掩码做与运算,

 备注一:

           所以这种方法需要通过位移来操作 在写抓屏程序的时候显示不如后边的32位图来的方便, 但是在颜色质量为16位的操作系统下如何抓屏到32位的图像呢

通过上边的两个GetDIBits的方法是不可行的  第一次LPVOID lpvBits, 为空 获得了BITMAPINFO bi信息bi.bmiHeader.biBitCount = 16;

如果想通过修改bi.bmiHeader.biBitCount = 32; 后来第二次调用GetDIBits就会失败 ;

那如何在颜色质量为16位的操作系统下如何获得32位的图像呢?

方法如下:

首先使用 GetObject(HBITMAP bmpScreen) 获得信息

然后通过修改BITMAPINFO   中的biBitCount 为32就可以获得32位结构的LPVOID 了 再进行操作就方便的多了

 view plaincopy

BITMAPINFO   bi = {0};       

bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);   

bi.bmiHeader.biWidth = bmpScreen.bmWidth;      

bi.bmiHeader.biHeight = bmpScreen.bmHeight;    

bi.bmiHeader.biPlanes = 1;      

bi.bmiHeader.biBitCount = 16;      

bi.bmiHeader.biCompression = BI_RGB;      

bi.bmiHeader.biSizeImage = 0;    

bi.bmiHeader.biXPelsPerMeter = 0;      

bi.bmiHeader.biYPelsPerMeter = 0;      

bi.bmiHeader.biClrUsed = 0;      

bi.bmiHeader.biClrImportant = 0;  

biBitCount=32

表示位图最多有2^32种颜色。这种位图的结构与16位位图结构非常类似,当biCompression成员的值是BI_RGB时,它也没有调色板,32位中有24位用于存放RGB值,顺序是:最前一字节保留,红8位、绿8位、蓝8位。这种格式也被成为888 32位图。如果biCompression成员的值是BI_BITFIELDS时,原来调色板的位置将被三个DWORD变量占据,成为红、绿、蓝掩码,分别用于描述红、绿、蓝分量在32位中所占的位置。在Windows 95(or98)中,系统只接受888格式,也就是说三个掩码的值将只能是:0xFF0000、0xFF00、0xFF。而在NT系统中,你只要注意使掩码之间不产生重叠就行。

VB用GetDIBits找色

“不知道为什么返回的坐标和实际坐标不一样,有哪位路过的老师能指教一下么?”
----------
单就这个问题来说,DIB位图通常是自下而上的,原点为图形的左下角,这与通常以屏幕或窗口的左上角为原点的习惯有所不同,使用时把y值加个负号就行了

文章分享结束,getdibits和C++函数GetDIBits怎么用的答案你都知道了吗?欢迎再次光临本站哦!

getdibits(C++函数GetDIBits怎么用)

本文编辑:admin
: getdibits

更多文章:


网站搭建招标方案(网站建设投标书怎么写)

网站搭建招标方案(网站建设投标书怎么写)

“网站搭建招标方案”相关信息最新大全有哪些,这是大家都非常关心的,接下来就一起看看网站搭建招标方案(网站建设投标书怎么写)!本文目录网站建设投标书怎么写网站建设方案包括哪些内容网站建设方法电子商务网站建设方案范文招标流程及注意事项~烟台网站

2025年8月24日 14:45

cpu script是什么意思(script是什么意思)

cpu script是什么意思(script是什么意思)

本篇文章给大家谈谈cpu script是什么意思,以及script是什么意思对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。本文目录script是什

2025年10月19日 07:00

he agreed to help(用need to do sth.和agree to do sth. 造句)

he agreed to help(用need to do sth.和agree to do sth. 造句)

各位老铁们,大家好,今天由我来为大家分享he agreed to help,以及用need to do sth.和agree to do sth. 造句的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我

2026年8月31日 01:00

instr函数的返回值(关于vb中InStr函数的一个小问题)

instr函数的返回值(关于vb中InStr函数的一个小问题)

今天给各位分享关于vb中InStr函数的一个小问题的知识,其中也会对关于vb中InStr函数的一个小问题进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录关于vb中InStr函数的一个小问题关于vb instr函

2026年1月26日 22:30

slcp是什么意思(matlab.*和matlab. s有什么区别)

slcp是什么意思(matlab.*和matlab. s有什么区别)

大家好,如果您还对slcp是什么意思不太了解,没有关系,今天就由本站为大家分享slcp是什么意思的知识,包括matlab.*和matlab. s有什么区别的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!本文目录matlab

2026年1月3日 12:00

db2数据库update后想恢复(你好,SQL修改错了,修改前没有备份,请问怎么还原到修改前的数据,你知道吗可以给联系方式我请教一下)

db2数据库update后想恢复(你好,SQL修改错了,修改前没有备份,请问怎么还原到修改前的数据,你知道吗可以给联系方式我请教一下)

大家好,关于db2数据库update后想恢复很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于你好,SQL修改错了,修改前没有备份,请问怎么还原到修改前的数据,你知道吗可以给联系方式我请教一下的知识点,相信应该可以解决大家的一

2026年9月17日 12:00

在线转换器人民币($1.8换算成人民币等于多少)

在线转换器人民币($1.8换算成人民币等于多少)

大家好,在线转换器人民币相信很多的网友都不是很明白,包括$1.8换算成人民币等于多少也是一样,不过没有关系,接下来就来为大家分享关于在线转换器人民币和$1.8换算成人民币等于多少的一些知识点,大家可以关注收藏,免得下次来找不到哦,下面我们开

2026年5月23日 09:45

python速成(想学python有什么建议)

python速成(想学python有什么建议)

大家好,关于python速成很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于想学python有什么建议的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!本文目录想

2025年10月21日 19:30

assert python用法(python:assert_raises() 怎么用啊,有哪些参数 请说得详细些,先谢谢了!)

assert python用法(python:assert_raises() 怎么用啊,有哪些参数 请说得详细些,先谢谢了!)

大家好,今天小编来为大家解答以下的问题,关于assert python用法,python:assert_raises() 怎么用啊,有哪些参数 请说得详细些,先谢谢了!这个很多人还不知道,现在让我们一起来看看吧!本文目录python:ass

2026年7月11日 08:30

中国学术网官网首页(中国知网如何查外文文献)

中国学术网官网首页(中国知网如何查外文文献)

大家好,今天小编来为大家解答以下的问题,关于中国学术网官网首页,中国知网如何查外文文献这个很多人还不知道,现在让我们一起来看看吧!本文目录中国知网如何查外文文献教师论文发布在哪个网站中国知网如何查外文文献中国知网如何查外文文献如下:1、在知

2026年8月12日 09:15

尚德机构是正规培训吗(尚德机构是正规培训吗)

尚德机构是正规培训吗(尚德机构是正规培训吗)

大家好,今天小编来为大家解答以下的问题,关于尚德机构是正规培训吗,尚德机构是正规培训吗这个很多人还不知道,现在让我们一起来看看吧!本文目录尚德机构是正规培训吗尚德机构正规吗尚德教育真的是骗子吗尚德机构是正规的吗尚德机构怎么样尚德机构是否真的

2026年3月24日 12:15

在我们当中中文版下载(如何下载在我们之中超多职业)

在我们当中中文版下载(如何下载在我们之中超多职业)

本篇文章给大家谈谈在我们当中中文版下载,以及如何下载在我们之中超多职业对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录如何下载在我们之中超多职业《AmongUs在我们之中》配置要求一览如何下载在我们之中超多职业直接在百度里搜索

2026年9月14日 16:45

this is it歌词好诡异(Turn The Lights On的歌词翻译)

this is it歌词好诡异(Turn The Lights On的歌词翻译)

今天给各位分享Turn The Lights On的歌词翻译的知识,其中也会对Turn The Lights On的歌词翻译进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录Turn The Lights On的

2025年7月26日 02:30

tabletennis安卓游戏(table tennis touch多人游戏时提示game center断开链接怎么解决)

tabletennis安卓游戏(table tennis touch多人游戏时提示game center断开链接怎么解决)

各位老铁们好,相信很多人对tabletennis安卓游戏都不是特别的了解,因此呢,今天就来为大家分享下关于tabletennis安卓游戏以及table tennis touch多人游戏时提示game center断开链接怎么解决的问题知识,

2025年8月8日 17:15

周杰伦什么时候出专辑(周杰伦的第一张专辑是什么时候)

周杰伦什么时候出专辑(周杰伦的第一张专辑是什么时候)

大家好,周杰伦什么时候出专辑相信很多的网友都不是很明白,包括周杰伦的第一张专辑是什么时候也是一样,不过没有关系,接下来就来为大家分享关于周杰伦什么时候出专辑和周杰伦的第一张专辑是什么时候的一些知识点,大家可以关注收藏,免得下次来找不到哦,下

2026年4月8日 15:00

cad三维制图入门教程(cad初学者怎么入门)

cad三维制图入门教程(cad初学者怎么入门)

各位老铁们好,相信很多人对cad三维制图入门教程都不是特别的了解,因此呢,今天就来为大家分享下关于cad三维制图入门教程以及cad初学者怎么入门的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!本文目录cad初学者怎么入门

2026年8月15日 23:45

迷你qq头像(2021头像可爱呆萌男生,寻找一些头像小男孩的那种)

迷你qq头像(2021头像可爱呆萌男生,寻找一些头像小男孩的那种)

这篇文章给大家聊聊关于迷你qq头像,以及2021头像可爱呆萌男生,寻找一些头像小男孩的那种对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。本文目录2021头像可爱呆萌男生,寻找一些头像小男孩的那种手机QQ如何设置隐形头像有什么好看的Q

2026年2月14日 13:00

微信上墙源码(如何制作微信墙)

微信上墙源码(如何制作微信墙)

今天给各位分享如何制作微信墙的知识,其中也会对如何制作微信墙进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录如何制作微信墙微信墙怎么做微信墙的运行原理微信墙的制作方法微信墙PHP源码在哪下载微信上墙!如何制作微

2026年1月12日 04:45

楷体字是什么样的?楷书可以分为哪几种

楷体字是什么样的?楷书可以分为哪几种

今天给各位分享楷体字是什么样的的知识,其中也会对楷体字是什么样的进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录楷体字是什么样的楷书可以分为哪几种什么是楷书楷书是常见的字体,四大楷体分别指的是什么楷体怎么写楷书

2025年8月8日 20:15

write的过去式和ing形式(初一所有动词的过去式)

write的过去式和ing形式(初一所有动词的过去式)

大家好,write的过去式和ing形式相信很多的网友都不是很明白,包括初一所有动词的过去式也是一样,不过没有关系,接下来就来为大家分享关于write的过去式和ing形式和初一所有动词的过去式的一些知识点,大家可以关注收藏,免得下次来找不到哦

2026年4月15日 04:15

近期文章

本站热文

electronics软件(labcenter electronics是什么软件)
2025-05-22 23:45:02 浏览:134
博客是微博吗(博客是微博吗)
2025-05-22 22:45:01 浏览:111
diversity and distribution(悬赏英语短文)
2025-05-23 16:15:02 浏览:107
ios软件开发前景(iOS就业前景怎么样)
2025-05-22 23:00:01 浏览:102
next month(有The next month这个单词吗,和 next month有什么区别)
2025-05-23 02:30:01 浏览:102
patron(patron是什么意思)
2025-05-23 10:30:02 浏览:95
标签列表

热门搜索