位图概述

位图格式
位图文件头
结构包含关于类型,大小以及与设备无关的文件层。
typedef struct tagBITMAPFILEHEADER {
  WORD bfType;
  DWORD bfSize;
  WORD bfReserved1;
  WORD bfReserved2;
  DWORD bfOffBits;
} BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER {
  DWORD biSize;                        // 大小
  LONG biWidth;                        // 宽度
  LONG biHeight;                       // 高度
  WORD biPlanes;                       // 平面?
  WORD biBitCount                      // 为个数
  DWORD biCompression;                 // 压缩
  DWORD biSizeImage;                   // 图像大小
  LONG biXPelsPerMeter;                // 每公尺X上的像素
  LONG biYPelsPerMeter;                // 每公尺Y上的像素
  DWORD biClrUsed;                     // ???
  DWORD biClrImportant;                // ???
} BITMAPINFOHEADER;
位图信息头

该结构体包含关于与颜色格式相关的设备无关位图。

指定的颜色表内的颜色索引,该索引是在位土内被使用的。如果这个值是零。
如果biClrUsed是非零值且biBitCount值小于16, biClrUsed成员指定实际图形引擎或设备驱动的存取值。
biClrImportant被指定的颜色索引必须显示在位图上。
如果颜色值是零,所有颜色是必须的。

目录

位图格式分析

一.位图文件存储格式

二.BitmapFileHeader

三.BitmapInfo

四.BitmapInfoHeader

五.BitmapData

六.保存位图为文件

1. 错误信息函数

2. 建立位图信息结构体函数

3. 建立位图文件函数

4. 保存位图到文件函数

七.从文件加载位图

1.错误信息函数

2. 从位图文件加载图象函数

一.位图文件存储格式

位图文件存储格式请参考图1.1。

图1.1 位图文件存储格式

图说明请参考表1.1。

表1.1 位图文件存储格式说明

结构体

说明

BitmapFileHeader

位图文件信息头

BitmapInfo

位图信息,由以下两个结构体组成

BitmapInfoHeader

位图信息头

RGBQUAD

颜色表

BitmapData

位图数据

二.BitmapFileHeader

typedef struct tagBITMAPFILEHEADER { // bmfh

WORD    bfType;

DWORD   bfSize;

WORD    bfReserved1;

WORD    bfReserved2;

DWORD   bfOffBits;

} BITMAPFILEHEADER;

bfType:文件类型,0x4d42,也就是BM

bfSize:文件大小,计算方法是
位图文件头大小【sizeof(BITMAPFILEHEADER)】
+位图信息头大小【pbih->biSize】
+颜色表大小【pbih->biClrUsed*sizeof(RGBQUAD)】
+位图数据大小【pbih->biSizeImage】

bfReserved1:预留字段,为0。

bfReserved2:预留字段,为0。

bfOffBits:图象数据的偏移量,计算方法是
位图文件头大小【sizeof(BITMAPFILEHEADER)】
+位图信息头大小【pbih->biSize】
+颜色表大小【pbih->biClrUsed*sizeof(RGBQUAD)】

三.BitmapInfo

typedef struct tagBITMAPINFO { // bmi

BITMAPINFOHEADER bmiHeader;

RGBQUAD          bmiColors[1];

} BITMAPINFO;

bmiHeader:位图信息头,见下节的结构体说明。

bmiColors:RGB颜色表数组。一般不存储到位图,在GetDIBits时将丢失这个信息,biClrUsed将被设置为0。

四.BitmapInfoHeader

typedef struct tagBITMAPINFOHEADER{ // bmih

DWORD biSize;

LONG   biWidth;

LONG   biHeight;

WORD   biPlanes;

WORD   biBitCount

DWORD biCompression;

DWORD biSizeImage;

LONG   biXPelsPerMeter;

LONG   biYPelsPerMeter;

DWORD biClrUsed;

DWORD biClrImportant;

} BITMAPINFOHEADER;

biSize:结构体大小。

biWidth:位图宽度,象素。对应位图宽度,bmp.bmWidth。

biHeight:位图高度,象素。对应位图高度,bmp.bmHeight。

biPlanes:调色板数目,一般是1。对应位图调色板数目,bmp.bmPlanes。

biBitCount:颜色位数。对应位图bmp.bmBitsPixel。

biClrUsed:使用的颜色数,在24位以下时需要使用,计算方法
if(cClrBits < 24) pbmi->bmiHeader.biClrUsed=(1<<cClrBits);

biSizeImage:图象数据大小,计算方法
位图宽度象素数目转换成字节【(pbmi->bmiHeader.biWidth+7)/8】
*位图高度象素数目【pbmi->bmiHeader.biHeight】
*象素位数【cClrBits】

注:宽度象素数目+7再除以8,用来处理余数的情况,如位图宽度为2,除以8为0,所以要+7再除以8。

五.BitmapData

24位位图图象数据的存储是RGB序列,在windows中是BGR序列:

象素B蓝色分量值

象素G绿色分量值

象素R红色分量值

32位位图象素数据的存储是RGBA序列,A是Alpha值,windows是BGRA序列:

象素B蓝色分量值

象素G绿色分量值

象素R红色分量值

象素alpha分量值

16位图象的分布是:

最高位保留,为0

高5位,红色分量

中间5位,绿色分量

最低5位,蓝色分量

六.保存位图为文件

可以将程序中的图象保存为文件,具体代码如下:

1. 错误信息函数

//错误信息

void exitWND(LPCTSTR msg)

{

MessageBox(NULL,msg,"Error",0);

exit(0);

}

2. 建立位图信息结构体函数

//建立位图信息结构体

PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp)

{

BITMAP bmp;

if(!GetObject(hBmp,sizeof(BITMAP),&bmp))

exitWND("Error when get object from hbitmap");

//获取颜色位数

WORD cClrBits;

cClrBits=(WORD)(bmp.bmPlanes*bmp.bmBitsPixel);

if(cClrBits == 1)

cClrBits=1;

else if(cClrBits <= 4)

cClrBits=4;

else if(cClrBits <= 8)

cClrBits=8;

else if(cClrBits <= 16)

cClrBits=16;

else if(cClrBits <= 24)

cClrBits=24;

else cClrBits=32;

//分配位图信息结构体

PBITMAPINFO pbmi;

if(cClrBits != 24)

pbmi=(PBITMAPINFO)

LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*(1<<cClrBits));

else

pbmi=(PBITMAPINFO)

LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER));

//初始化位图结构体

pbmi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);

pbmi->bmiHeader.biWidth=bmp.bmWidth;

pbmi->bmiHeader.biHeight=bmp.bmHeight;

pbmi->bmiHeader.biPlanes=bmp.bmPlanes;

pbmi->bmiHeader.biBitCount=bmp.bmBitsPixel;

if(cClrBits < 24)

pbmi->bmiHeader.biClrUsed=(1<<cClrBits);

//不压缩位图

pbmi->bmiHeader.biCompression=BI_RGB;

//初始化图象数据大小

pbmi->bmiHeader.biSizeImage=

(pbmi->bmiHeader.biWidth+7)/8

*pbmi->bmiHeader.biHeight

*cClrBits;

//所有的设备颜色都重要

pbmi->bmiHeader.biClrImportant=0;

//返回指针

return pbmi;

}

3. 建立位图文件函数

//建立位图文件

void CreateBMPFile(LPTSTR pszFile,PBITMAPINFO pbi,HBITMAP hBmp,HDC hDC)

{

PBITMAPINFOHEADER pbih=(PBITMAPINFOHEADER)pbi;

LPBYTE lpBits;

lpBits=(LPBYTE)GlobalAlloc(GMEM_FIXED,pbih->biSizeImage);

if(!lpBits)

exitWND("error to global alloc memory");

//获取位图图象数据

GetDIBits(hDC,hBmp,0,(WORD)pbih->biHeight,lpBits,pbi,DIB_RGB_COLORS);

//建立位图文件

HANDLE hf;

hf=CreateFile(pszFile,GENERIC_READ|GENERIC_WRITE,

NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

if(hf == INVALID_HANDLE_VALUE)

exitWND("error to create file");

//建立位图文件信息头

BITMAPFILEHEADER hdr;

hdr.bfType=0x4d42;

hdr.bfSize=(DWORD)(sizeof(BITMAPFILEHEADER)+

pbih->biSize+pbih->biClrUsed*sizeof(RGBQUAD)+

pbih->biSizeImage);

hdr.bfReserved1=0;

hdr.bfReserved2=0;

//计算位图数据偏移量

hdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+

pbih->biSize+pbih->biClrUsed*sizeof(RGBQUAD);

//写入位图文件头

DWORD wt;

if(!WriteFile(hf,(LPVOID)&hdr,sizeof(BITMAPFILEHEADER),&wt,NULL))

exitWND("error when write bitmap file header");

//写入位图信息头

if(!WriteFile(hf,(LPVOID)pbih,

sizeof(BITMAPINFOHEADER)+pbih->biClrUsed*sizeof(RGBQUAD),

&wt,NULL))

exitWND("error when write bitmap info header and RGBquad");

//写入位图数据

if(!WriteFile(hf,(LPVOID)lpBits,pbih->biSizeImage,&wt,NULL))

exitWND("error when write data");

//关闭文件

if(!CloseHandle(hf))

exitWND("error when close file handle");

//释放图象数据所占内存

GlobalFree(lpBits);

}

4. 保存位图到文件函数

//保存位图到文件

void SaveBitmapFile(LPTSTR fileName,HWND hWnd,HBITMAP bmp)

{

PBITMAPINFO pbmi;

pbmi=CreateBitmapInfoStruct(bmp);

HDC hdc;

hdc=GetDC(hWnd);

CreateBMPFile(fileName,pbmi,bmp,hdc);

ReleaseDC(hWnd,hdc);

}

七.从文件加载位图

从文件加载位图,用ReadFile定位文件需要使用OVERLAPPED,展开位图到DC使用StretchDIBits函数。代码如下:

1.错误信息函数

//错误信息

void exitWND(LPCTSTR msg)

{

MessageBox(NULL,msg,"Error",0);

exit(0);

}

2. 从位图文件加载图象函数

//从位图文件加载图象

HBITMAP LoadBitmapFile(LPCTSTR fileName,HWND hWnd)

{

//打开文件

HANDLE hf;

hf=CreateFile(fileName,GENERIC_READ,FILE_SHARE_READ,

NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);

if(hf == INVALID_HANDLE_VALUE){

exitWND("error when open file handle");

return 0x00;

}

//展开位图文件到DC

DWORD read;

//读取文件信息头

BITMAPFILEHEADER bfh;

OVERLAPPED olbfh;

memset(&olbfh,0,sizeof(OVERLAPPED));

olbfh.Offset=0;

ReadFile(hf,&bfh,sizeof(bfh),&read,&olbfh);

//读取位图信息

BITMAPINFO bi;

OVERLAPPED olbi;

memset(&olbi,0,sizeof(OVERLAPPED));

olbi.Offset=sizeof(BITMAPFILEHEADER);

ReadFile(hf,&bi.bmiHeader,sizeof(bi.bmiHeader),&read,&olbi);

//读取位图数据

LPBYTE lpBits;

lpBits=(LPBYTE)GlobalAlloc(GMEM_FIXED,bi.bmiHeader.biSizeImage);

OVERLAPPED ollpbits;

memset(&ollpbits,0,sizeof(OVERLAPPED));

ollpbits.Offset=bfh.bfOffBits;

ReadFile(hf,lpBits,bi.bmiHeader.biSizeImage,&read,&ollpbits);

//建立和窗口关联的DC

HDC hdc;

hdc=GetDC(hWnd);

HDC mem;

mem=CreateCompatibleDC(hdc);

//建立和DC关联的位图

HBITMAP bmp;

bmp=CreateCompatibleBitmap(hdc,bi.bmiHeader.biWidth,bi.bmiHeader.biHeight);

SelectObject(mem,bmp);

//在DC中展开

StretchDIBits(mem,

0,0,bi.bmiHeader.biWidth,bi.bmiHeader.biHeight,

0,0,bi.bmiHeader.biWidth,bi.bmiHeader.biHeight,

(LPVOID)lpBits,&bi,DIB_RGB_COLORS,SRCCOPY);

//清理工作

GlobalFree(lpBits);

DeleteDC(mem);

ReleaseDC(hWnd,hdc);

CloseHandle(hf);

//返回位图对象

return bmp;

}

Windows位图文件格式[转]相关推荐

  1. Windows位图和调色板

    很详细的介绍了bitmap和palette,其实这些知识在读研期间也学习整理过,由于当时没有用博客记录下来,并且这两三年的工作主要集中在Audio这一块,Video相关的基本知识记忆有点模糊了,现在又 ...

  2. vim windows linux文件格式转换

    vim windows linux文件格式转换 set ff?     #显示当前文件格式 set ff=unix     #设置成unix格式 set ff=dos #设置成dos格式 posted ...

  3. windows 位图结构详解

    位图文件可看成由4个部分组成:位图文件头(bitmap-file header).位图信息头(bitmap-information header).彩色表(color table)和定义位图的字节阵列 ...

  4. Windows 位图

    目 录 第1章 简介    1 1.1 DFB    1 1.2 DDB    1 1.3 DIB    2 第2章 相关API    3 2.1 创建    3 2.1.1 CreateCompat ...

  5. RGB565与RGB555位图文件格式的标志识别

    最近从一张本地的16位位图读取像素颜色数据,并填充到ANDROID的BITMAP的数据中,发现使用CAVAS显示到界面时,图片显示颜色不对,找了很多资料,原来发现是两个原因: 1.将位图的颜色分量掩码 ...

  6. linux下文件与Windows下文件格式的区别与转换

    问题: Windows下的TXT文件上传到Linux系统上,用cut,grep.sed,awk等文本处理工具处理过后再次传到Windows电脑上,发现内容都连到一块了,百度了一下才知道换行符被删除了, ...

  7. Windows Unix 文件格式之迷

    (1)问题提出 我们可能会遇到过这样一些困惑: A, 如何查看一个文件或数据流的二进制格式(以十六进制格式显示)? B,为什么在 windows下编辑的 shell 脚本在 Unix下不能执行?为什么 ...

  8. Windows Unix 文件格式之迷, 空格、回车换行、tab 转换及其相关工具 .

    http://casec12.javaeye.com/blog/523160 今天,我总算搞清楚"回车"(carriage return)和"换行"(line ...

  9. 图解 bmp 文件(BITMAP,windows位图文件)格式

    既然是图解,此处省去介绍....直接上图 以下代码中SetPixel()为在屏幕中打点的函数,在单片机中由自己实现, 根据不同的位深来解析,都是根据以上图片方式,推导出来的算法. 并没有实现压缩算法, ...

最新文章

  1. 双目视觉惯性里程计的在线初始化与自标定算法
  2. java pdf转换为png图片(1)
  3. NAT的完全分析及其UDP穿透的完全解决方案
  4. 横河压力变送器选型_压力变送器的原理和选型技巧
  5. python开发微信小程序-Python实现微信小程序支付功能
  6. 使用HANA studio创建XS project
  7. 采用计算机辅助电话调查,计算机辅助电话调查(CATI)-实验.pdf
  8. 简单的C语言五子棋(两种模式:移动光标输入坐标和移动光标按键)
  9. linux 局域网内互ping丢包_ping命令还能这么用?
  10. php 精度比较,PHP浮点数精度和比较
  11. iterator adapter reverse_iterator
  12. c语言头文件及形式,C语言头文件作用及写法
  13. 企业设计图纸 无纸化图纸管理方案
  14. 系统运维安全管理办法_7.系统运维安全管理规定
  15. 滴滴新出的移动端UI组件库 Mand Mobile,提前蹭个热度
  16. 实例讲解新GRE填空的变化
  17. 数字转换 LibreOJ - 10155
  18. 数字图像处理作业-医学图像浏览器
  19. 微服务(四)——统一网关
  20. [CSP-S模拟测试]:壕游戏(费用流)

热门文章

  1. python 显示界片_任何快速的python图形用户界面都可以显示摄像机的实时图像
  2. 【SPSS】回归分析详细操作教程(附案例实战)
  3. 数组的归一化c语言,如何归一化频率数组
  4. 【Windows 11】系统安装修改版 Subsystem for Android 安卓子系统,并用 Magisk Root
  5. 双向可控硅触发电路的设计方案
  6. easyUI之LinkButton(按钮)
  7. 13种加密与解密算法【一】
  8. matlab输出数据为excel文件
  9. DJ2-2 进程管理
  10. 【蓝桥杯嵌入式主板G4】第三章 点亮一个LED