文档章节

bmp位图分析

blackylin
 blackylin
发布于 2012/11/07 12:01
字数 905
阅读 265
收藏 3

这里简单描述下之前文章中(android底层实现鼠标状态更换对应的光标图像)光标图像用到的解析位图。

1.bmp位图格式
为了更容易了解bmp,咱先用个纯黑色的bmp图片为例:

ultraEdit打开,16进制如下:

00000000h: 42 4D D2 09 00 00 00 00 00 00 36 00 00 00 28 00 ; BM?......6...(.
00000010h: 00 00 36 00 00 00 0F 00 00 00 01 00 18 00 00 00 ; ..6.............
00000020h: 00 00 9C 09 00 00 C4 0E 00 00 C4 0E 00 00 00 00 ; ..?..?..?....
00000030h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000040h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000050h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
......//省略下面
......

前面54个字节表示头:

00000000h: 42 4D D2 09 00 00 00 00 00 00 36 00 00 00 28 00 ; BM?......6...(.
00000010h: 00 00 36 00 00 00 0F 00 00 00 01 00 18 00 00 00 ; ..6.............
00000020h: 00 00 9C 09 00 00 C4 0E 00 00 C4 0E 00 00 00 00 ; ..?..?..?....
00000030h: 00 00 00 00 00 00

其中第16-19个字节表示位图长00 00 00 36(十进制54),20-23个字节表示宽00 00 00 0F(十进制15);
像素个数=长*宽=54*15=810
图像总大小=像素个数*3(3个字节表示一个像素点,分别为r,g,b)+头=810*3+54=2430+54=2484
(注:但这张图片的实际大小是2514字节,少了30个字节,这不科学╮(╯▽╰)╭。有哪位朋友知道告诉我下,谢谢)

这个计算方法应该是没有错误的,我这里再发个图片,大家可以按照这个方法来计算下

实际大小:1206字节=12*32*3+54=1152+54=1206
长:12
宽:32

好了,这里大家应该简单知道bmp位图的各个表示含义了。接下来就是就转成带透明色的32位位图:
其实刚才已经说过了,bmp是3个字节表示一个像素,分别为(r,g,b),而这里我们就是要在每个像素里增加一个alpha位,
变成(r,g,b,a),所以位图大小会变成:长*宽*4

透明色:我自己的理解是透明色只是相对的,当你要把图片里面的黑色部分完全透明掉的话:00 00 00(表示黑色),可以
直接00 00 00 00;否则则为:00 00 00 ff.下面给出我android里面的一个代码:

//buffer第54个后的为图像数据
				byte[] by1=Arrays.copyOfRange(buffer, 54, buffer.length);
				
				//24位图转32位,由于bmp存储是从后面往前面,所以需要倒序进行转换
				byte[] by2=new byte[width*height*4];
				for(int j=0;j<height;j++){
					for(int k=0;k<width;k++){
						by2[(height-j-1)*width*4+4*k]=by1[(j*width*3+3*k)];
						by2[(height-j-1)*width*4+4*k+1]=by1[(j*width*3+3*k+1)];
						by2[(height-j-1)*width*4+4*k+2]=by1[(j*width*3+3*k+2)];
						if(by2[(height-j-1)*width*4+4*k]==(byte) 0x00 &&
								by2[(height-j-1)*width*4+4*k+1]==(byte) 0x00 &&
								by2[(height-j-1)*width*4+4*k+2]==(byte) 0x00){
							by2[(height-j-1)*width*4+4*k+3]=(byte) 0x00;
						}else{
							by2[(height-j-1)*width*4+4*k+3]=(byte) 0xff;
						}
					}
				}

最后有个有意思的地方就是:bmp存储数据是倒序的,解析数据时必须从后面往前面。
给出一个测试建议:

在位图16进制里前面部分修改数据,如00改成ff等,你会发现在位图的左下角有其他像素(红绿蓝等)

这里我有个疑问:

既然是倒序存储的为什么不是从右下角出现修改后的其他像素呢?

要是有朋友知道,希望不吝赐教,thks,O(∩_∩)O~

© 著作权归作者所有

blackylin
粉丝 48
博文 46
码字总数 27849
作品 0
深圳
Android工程师
私信 提问
android底层实现鼠标状态的图标

今天这里贴出从应用层传出一个id或图片byte[]数组,通过aidl与service交互调用JNI,最后到Cursor.c实现画不同状态的光标。下面就给出Cursor.c的实现画图,前面的过程就不全给出了: Cursor.c...

blackylin
2012/08/09
1K
0
BMP图形文件分析类(c#)

1using System; 2using JJBase.FILE; 3namespace JJBase.Image 4{ 5 /**//// 6 /// BMP 的摘要说明。 7 /// 8 public class BMP 9 { 10 11 public BMP() 12 { 13 // 14 //TODO: 在此处添加构......

晨曦之光
2012/03/09
152
0
数据压缩原理与应用 图像文件的读写和转换(BMP2YUV)实验报告

一、实验原理 1.BMP文件的组成结构 BMP(全称 Bitmap )是Windows操作系统中的标准图像文件格式 ,可以分成两类:设备相关位图(DDB )和设备无关位图( DIB),使用非常广。它采用位映射存...

zgyggy
2017/03/22
0
0
python 常用内建模块之struct

python学习笔记,特做记录,分享给大家,希望对大家有所帮助。 struct 准确地讲,Python没有专门处理字节的数据类型。但由于b'str'可以表示字节,所以,字节数组=二进制str。而在C语言中,我...

展菲
07/26
0
0
vc bmp对象与Opencv Iplimage对象相互转换

首先我们要了解两种数据结构 IplImag 对象结构: /************************************************************************************************** * * * NOTE: * * Only use the "......

长平狐
2012/07/12
236
0

没有更多内容

加载失败,请刷新页面

加载更多

代理模式之JDK动态代理 — “JDK Dynamic Proxy“

动态代理的原理是什么? 所谓的动态代理,他是一个代理机制,代理机制可以看作是对调用目标的一个包装,这样我们对目标代码的调用不是直接发生的,而是通过代理完成,通过代理可以有效的让调...

code-ortaerc
今天
5
0
学习记录(day05-标签操作、属性绑定、语句控制、数据绑定、事件绑定、案例用户登录)

[TOC] 1.1.1标签操作v-text&v-html v-text:会把data中绑定的数据值原样输出。 v-html:会把data中值输出,且会自动解析html代码 <!--可以将指定的内容显示到标签体中--><标签 v-text=""></......

庭前云落
今天
8
0
VMware vSphere的两种RDM磁盘

在VMware vSphere vCenter中创建虚拟机时,可以添加一种叫RDM的磁盘。 RDM - Raw Device Mapping,原始设备映射,那么,RDM磁盘是不是就可以称作为“原始设备映射磁盘”呢?这也是一种可以热...

大别阿郎
今天
12
0
【AngularJS学习笔记】02 小杂烩及学习总结

本文转载于:专业的前端网站☞【AngularJS学习笔记】02 小杂烩及学习总结 表格示例 <div ng-app="myApp" ng-controller="customersCtrl"> <table> <tr ng-repeat="x in names | orderBy ......

前端老手
昨天
16
0
Linux 内核的五大创新

在科技行业,创新这个词几乎和革命一样到处泛滥,所以很难将那些夸张的东西与真正令人振奋的东西区分开来。Linux内核被称为创新,但它又被称为现代计算中最大的奇迹,一个微观世界中的庞然大...

阮鹏
昨天
20
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部