HBITMAP与BITMAP 的区别 BMP图像的格式

2023-05-16

HBITMAP   是句柄;  
BITMAP    是实例:  

typedef struct tagBITMAP {  /* bm */
    int     bmType;//必须是BM
    int     bmWidth;//指定位图的宽度(以象素为单位)
    int     bmHeight;//指定位图的高度(以象素为单位)。
    int     bmWidthBytes;//一行几个字节,4位对齐
    BYTE    bmPlanes;//指定目标设备的位面数
    BYTE    bmBitsPixel;//指定每个象素的位数
    LPVOID  bmBits;//指向图象数据的指针

} BITMAP;

注意 bmBits是自己先前设置的  具体看下面复制的:

CBitmap::CreateBitmapIndirect函数的功能是用一个BITMAP结构体重的高度、宽度和位模式(如果指定了一个的话)来初始化一个位图。调用该函数时,用户可以设置bmBits字段为NULL或者设为像素位数据的地址(用以初始化该位图)。
复制自:http://bbs.csdn.net/topics/10310605

所以如果我们生成位图的时候没有设置bmBits  ,之后通过下面的 方法得到的bm结构中的bmBits是NULL   是无效的指针   

这时候我们可以通过GetDIBits获得bmp图像的DIB格式的数据.  我们传入的第6个参数 即LPBITMAPINFO  结构体会接收返回的位图信息 比如位图数据大小     具体见下面BITMAPINFOHEADER的解释 

    

windows不允许直接对用户对象操作,其操作得通过句柄来进行。  

例如:
  HBITMAP   hBmp;  
  BITMAP   bm;  
  GetObject(hBmp,sizeof(bm),&bm);  

通过HBITMAP取得BITMAP;

以下不是转载  而是个人理解  不对请指正:注意上面得到的bm是hBmp的信息  它表示的是hBmp的固有属性  假如它是与你的屏慕兼容的bmp   那么hBmp的信息记录的是屏幕位图的信息 不会改变。

GetDIBits 当你用位图去获取信息时,获取信息的位数 什么的 跟你传入的BITMAPINFO结构有关系 假如这个bmp已经被选入屏幕DC  你要获得屏幕的8位图像(256色) 而一般你的屏幕是32位  那么bm中存放的 bmBitsPixel是32   而你想到8位的话 就 需要在BITMAPINFO结构中设置 然后给GetDIBits作参数!

 



BMP图像   以下是有部分信息是摘抄自其它网友的   

由四部分组成:

A. 第一部分为位图文件头BITMAPFILEHEADER,它是一个结构体,定义如下:

typedef struct tagBITMAPFILEHEADER{

     WORD    bfType; /文件类型,必须是0x424D,即字符串“BM”

     DWORD   bfSize; /指定文件大小,包括这14个字节

     WORD    bfReserved1; /保留字,不用考虑

     WORD    bfReserved2; /保留字,不用考虑

     DWORD   bfOffBits; /从文件头到实际位图数据的偏移字节数

}BITMAPFILEHEADER;

这个结构的长度是固定的,为14个字节(WORD为无符号16位二进制整数,DWORD为无符号32位二进制整数)。

B. 第二部分为位图信息头BITMAPINFOHEADER,也是一个结构,定义如下:

typedef struct tagBITMAPINFOHEADER{

DWORD   biSize; /该结构的长度,为40

LONG      biWidth; / 图像的宽度,单位是像素

LONG      biHeight; / 图像的高度,单位是像素

WORD      biPlanes; / 位平面数,必须是1,不用考虑

WORD      biBitCount;/ 指定颜色位数,1为二值,4为16色,8为256色,16、24、32为真彩色 DWORD     biCompression; / 指定是否压缩,有效的值为BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS

DWORD     biSizeImage; / 实际的位图数据占用的字节数

LONG      biXPelsPerMeter; / 目标设备水平分辨率,单位是每米的像素数

LONG      biYPelsPerMeter; / 目标设备垂直分辨率,单位是每米的像素数

DWORD     biClrUsed;/实际使用的颜色数,若该值为0,则使用颜色数为2的bitBitCount次方种

DWORD     biClrImportant; /图像中重要的颜色数,若该值为0,则所有的颜色都是重要的

} BITMAPINFOHEADER;

这个结构的长度是固定的,为40个字节(LONG为32为二进制整数)。

偏移 域的名称 长度/字节 内容
000Eh(14) biSize 4
文件信息头的长度
40(28h):Windows
00012h(18) biWidth 4 位图的宽度,以像素为单位
00016h(22) biHeight 4 位图的高度,以像素为点为
001Ah(26) Biplanes 2 位图的为平面数(该值总是为1)
001Ch(28) biBitCount 2
每个像素的位平面数,有下面几种情况:
1:单色位图
4:16色位图
8:256色位图
16:16bit高彩色位图
24:24bit真彩色位图
32:32bit增强型真彩色位图
001Eh(30) biCompression 4
压缩说明:
0:不压缩(用BI_RGB表示)
1:RLE8,使用8位RLE压缩方式(用BI_RLE8表示)
2:RLE4,使用4位RLE压缩方式(用BI_RLE4表示)
3:Bitfields:位域存放方式(用BI_BITFIELDS表示)
0022h(34) biSizeImage 4 位图数据的大小,以字节为单位。该数必须是4的倍数。当图像存储的是非压缩数据的时候,它的取值可以为0,实际上,此时位图数据的大小可以通过biBitCount,biWidth,biHeight等计算出来
0026h(38) biXPelsPerMeter 4 用像素/米表示的水平分辨率
002Ah(42) biYPelsPerMeter 4 用像素/米表示的垂直分辨率
002Eh(46) biClrUsed 4 位图使用的颜色数,如果为0则表示使用了全部可能的颜色
0032h(50) biClrImportant 4 指定重要的颜色数。当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要

C. 第三部分为调色板(Palette),当然,这里是对那些需要调色板的位图文件而言的。真彩色图像不需要调色板,BITMAPINFOHEADER后直接是位图数据。调色板实际上是一个数组,共有biClrUsed个元素(如果该值为零,则有2的biBitCount次方个元素)。数组中每个元素的类型是一个RGBQUAD结构,占4个字节,其定义如下:

    typedef struct tagRGBQUAD

{

       BYTE rgbBlue;   //该颜色的蓝色分量

       BYTE rgbGreen;   //该颜色的绿色分量

       BYTE rgbRed;     //该颜色的红色分量

       BYTE rgbReserved;//保留值

} RGBQUAD;

D.第四部分是实际的图像数据,对于用到调色板的位图,图像数据就是该像素颜色在调色板中的索引值,对于真彩色图像,图像数据就是实际的R、G、B值:

• 对于2色位图:用1位就可以表示该像素的颜色(一般0表示黑,1表示白),所以一个

字节就可以表示8个像素;

• 对于16色位图,用4位可以表示一个像素的颜色,所以一个字节可以表示2个像素;

• 对于256色位图,一个字节刚好可以表示1个像素;

色深24位的位图

★     每一行的字节数必须是4的整数倍,如果不是,则需要补齐;(bitSizeImage中提到过)

★     BMP文件的数据存放是从下到上,从左到右的。也就是说,从文件中最先读到的是图像最下面的左边第一个像素,然后是左边第二个像素,接下来是倒数第二行左边第一个像素,左边第二个像素,依次类推

每个像素用3个字节表示,顺序依次为红,绿和蓝的值。每行用0填充到4字节的边界。



读取图像数据的方法:

HBITMAP hBmp = (HBITMAP)LoadImage( NULL , "z:\\bg4.bmp" , IMAGE_BITMAP , 0 , 0 , LR_CREATEDIBSECTION | LR_LOADFROMFILE);
 if (hBmp != NULL)
 {
  BITMAP bmp = {0};
  int ret = GetObject( hBmp , sizeof(BITMAP) , &bmp );
  if (ret)
  {
   TRACE( "Width = %d Height = %d BitsPerPixel = %d\n" , bmp.bmWidth , bmp.bmHeight , bmp.bmBitsPixel );

   BYTE* pPixel = (BYTE*)bmp.bmBits;  //指向BMP像素的指针

   int x = 1439 , y = 899;  //指定要获取像素的坐标  规定图片左上角坐标为0,0

   BYTE *pOffset = pPixel + (bmp.bmHeight - 1) * bmp.bmWidthBytes;  //指向最后一行像素数据

   pOffset =  (pOffset -  y * bmp.bmWidthBytes) + x * bmp.bmBitsPixel / 8; //指向指定像素位置

   DWORD rgb = 0;

   memcpy( &rgb , pOffset , bmp.bmBitsPixel / 8 );

   TRACE( "(x = %d y = %d) = %u\n" , x , y , rgb );

  }
  
  DeleteObject( hBmp );
  hBmp = NULL;
  ZeroMemory( &bmp , sizeof(bmp) );
 }
//上面代码里的rgb就是你要的像素了

//如果你是在对话框之类的处理的话可以用类似下面的代码实现
CDC* pDc = GetDC();
 POINT pt;
 pt.x = 10;
 pt.y = 10;
 pDc->SetPixel( pt , RGB(255,0,0) );



部分摘抄来自http://blog.sina.com.cn/s/blog_48f0f4da0100c3es.html

      http://blog.sina.com.cn/s/blog_49dd59fe01011wbj.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HBITMAP与BITMAP 的区别 BMP图像的格式 的相关文章

  • 电脑键盘工作原理

    xfeff xfeff 随着IBM PC机的发展 xff0c 键盘也分为XT AT PS 2键盘以至于后来的USB键盘 PC系列机使用的键盘有83键 84键 101键 102键和104键等多种 XT和AT机的标准键盘分别为83键和84键 x
  • 十三、扩展一个组合导航系统

    感谢大神分享 xff1a https zhuanlan zhihu com p 156958777 一 概述 上一篇文章我们讲述了怎样搭建一个基本的组合导航系统 xff0c 它仅仅包括IMU做预测 GPS做观测 xff0c 而实际中 xff
  • 三、FSAS + Novatel接收机和相机时间同步、数据保存、解码等 细节说明

    一 器件说明 1 GNSS 接收机是 P ropak6 如下图所示 xff1a 具体得介绍 xff1a 1 https blog csdn net hltt3838 article details 110622732 2 二 NovAtel
  • Word 中出现公式不能编辑问题(兼容模式)

    当word中的公式不能编辑 xff0c 多数原因是由于word是处于兼容模式下 xff0c 这个时候就需要取消world的兼容模式 xff0c 具体步骤如下 xff1a 一 打开word文档 二 点击 word中的文件 出现如下结果 xff
  • 理论三、 MSCKF 数学基础

    感谢 xff1a 紫薯萝卜 https zhuanlan zhihu com p 76793847 1 数学定义 后续将进行MSCKF数学基础介绍 xff0c 先总结一下数据符号定义 坐标系定义 物理量定义 估计量定义 四元数定义 xff1
  • 算法改进5:开源算法Open VINS试用

    1 Open VINS简介 Open VINS是Huang Guoquan老师团队在2019年8月份开源的一套基于MSCKF的VINS算法 xff0c 黄老师曾是Tango项目的核心成员 xff0c 在MSCKF这块非常的权威 Github
  • MSCKF 公式推导

    看完这篇博客建议再看 xff1a http www xinliang zhong vip msckf notes 目录 一 简介 二 符号说明 三 状态向量 3 1 真实状态向量 true state 3 2 误差状态向量 error st
  • MSCKF 源码解析 一

    论文 xff1a https arxiv org abs 1712 00036 源码路径 https github com daniilidis group msckf mono 源码框架 上图展示了整个msckf源码框架 xff0c 每当
  • C++中 仿函数简单介绍

    仿函数 xff0c 顾名思义 xff0c 就是 仿造函数 的意思 xff0c 它并不是函数 xff0c 但是却有着类似于函数的行为 那么 xff0c 它到底是什么 xff1f 首先要说的是 xff1a 仿函数是泛型编程强大威力和纯粹抽象概念
  • GNSS/INS组合导航(八):INS/GPS组合导航

    INS GPS组合导航 对比INS与GPS导航方法 xff0c 二者都有其各自的优缺点 惯性导航系统INS是一种全自主的导航系统 xff0c 可以输出超过200Hz的高频信号 xff0c 并且具有较高的短期测量精度 除了提供位置与速度之外还
  • Word 中利用“多级列表“功能实现章节标题自动编号

    一 打开 多级列表 打开Word文档 xff0c 在 开始 选择多级列表 点击定义新的多级列表 xff1b 点击之后 xff0c 便可以得到下面的界面 xff1a 二 设置固定格式的 多级标题 假设我们需要下面的标题格式 xff0c 我们需
  • 端口映射怎么设置

    路由器端口映射的作用就是让互联网上的用户可以访问内网中的服务器 xff0c 内网的一台电脑要上因特网对外开放服务或接收数据 xff0c 都需要端口映射 端口映射分为动态和静态 动态端口映射 xff1a 内网中的一台电脑要访问某网站 xff0
  • 解决Word中出现的多级列表编号不显示的问题

    解决办法一 常见的办法是 xff1a 光标置于标题前方 xff0c 按 ctrl 43 xff0c 编号消失位置出现一小条灰色 xff0c 再按ctrl 43 shift 43 S 重新应用样式 确定 即可找回编号 注意 xff1a 但下次
  • GPS从入门到放弃(二十五)、卡尔曼滤波

    一 概述 单点定位的结果因为是单独一个点一个点进行的 xff0c 所以连续起来看数据可能出现上串下跳的情况 xff0c 事实上并不符合实际情况 为了解决这个问题 xff0c 考虑到物体运动的连续性和运动变化的缓慢性 xff0c 可以通过滤波
  • RealSenseD435i (一):Ubuntu18.04 下的安装、使用和bag录制 ,且解决 undefined symbol 问题(最简单的方法)

    注意 realsense ros 要和 librealsense 版本匹配 realsense ros 2 2 11 对应的 Realsense SDK 为 librealsense 2 31 0 否则后面会出现让人崩溃的问题 其中 nbs
  • ( C# + vs2017 )串口助手 零基础详细教程(二)

    感谢 xff1a 串口助手 简洁版 上位机软件零基础教程 xff08 C 43 visual studio2017 xff09 xff08 二 xff09 SWPU 机器人实验室 CSDN博客 在上篇博客中 xff0c 我们完成了串口助手
  • RTK定位技术原理

    RTK即载波相位差分技术 xff0c rtk定位能够实时地提供测站点在指定坐标系中的三维定位结果 xff0c 并达到厘米级精度 普通GPS的定位精度大于1米 xff0c 信号误差有50 的概率会达到2米以上 另外 xff0c GPS无法支持
  • Endnote的插件被禁止,始终加载不了 - 终极解决办法

    1 用管理员 的身份运行word xff1a 找到word 右键 以管理员的身份运行 2 打开一个word 文件 选项 加载项 转到 选择endnote cite while you write 点击删除 xff08 删除前记住你的endn
  • 高斯白噪声(white Gaussian noise,WGN)

    本文科普一下高斯白噪声 xff08 white Gaussian noise xff0c WGN xff09 百度百科上解释为 高斯白噪声 xff0c 幅度分布服从高斯分布 xff0c 功率谱密度服从均匀分布 xff0c 听起来有些晦涩难懂
  • 【3】IMU模块:PA-IMU-460 ROS驱动 + 与GNSS时间同步

    一 模块介绍 惯性测量单元 IMU 产品展示 西安精准测控有限责任公司 说明 这是一款国产的IMU模块 之所以选择这个是因为同等精度的产品价格8500元 这个只要2500元 缺点是 担心国产的模块性能不好 参数需要自己标定 二 程序运行 c

随机推荐