读取BMP图像size的时候与操作和左移的原因
在读取一个bmp图像的时候,我们会将它的大小读取出来,如果还不清楚bmp的文件结构,那就先看一下这篇博客。
看完我将假设你已经明白
所表示的意义。那么,对于bfSize, 它的表示数字为 50 00 00 00. 根据PC的显示习惯(其实就是小端存储规则),那么其真实值应该是00 00 00 50。 那么如果现在我们要提取出这个值,我们应该怎么做呢? 首先当然是将值从文件提取出来,这个简单,只需要将0-5的数据读取出来就可以了。假设读取出来的数据是放到一个数组sizeinfo里面的,那么现在sizeinfo[2]~sizeinfo[5]的数字就是我们想要的。
那么要怎么组合成一个数字呢?按照我们一般的想法,应该是 0*16^7 + 0*16^6 + 0*16^5 + 0*16^4 + 0*16^3 + 0*16^2 + 5*16^1 + 0*16^0.
那如果我们要这么计算的话是不是还要将50这样的数字解析成 5 和 0 呢?其实不用的。很明显用位操作可以简单完成工作。我们可以看看这份测试 
在这个测试里面,我假设原数字为 51 00。那么真实值应该为: 5*16^3 + 1*16^2. 在51里面,5其实是比1高一位的,那也就是说,我们只要关心1,而5自动会比1高一位。而对于1来说,16^2其实就是左移8位。所以我们只需要将51左移8位,这个时候因为5本身是高位,所以左移后它的值就是5*16^3。
所以综合起来,上图的bfSize就可以表示成如下:
intbfSize = (int) (byteList[5] << 24)
| (byteList[4] << 16)
| (byteList[3] << 8)
| (byteList[2]);
为什么是或操作呢?左移的时候,低位补的是0,而我们要把高位低位移位后的值加起来,其实也就是将对应的位给加上去。我们假设这样一个数字:51 01,那么应该是这样的:

那么,就是取或操作嘛。这样就能直接将低位的值加到高位后面了。
那么是这样就完成了吗?当然不是,从我推荐的那篇博客的介绍可以看出,图像里面储存的数值是用 byte 类型的。也就是 8 位。而 int 是32位的。另外,在java里面二进制采用的是补码的形式。
现在我们假设这样一个数字:0xff,这个时候因为我们表示图片 size 的时候是16进制,那么0xff 的实际值就不应该是 -1. 但是如果我们直接强制类型转换会怎样?java 会将0xff 当成 -1.然后位扩展成1111 1111 1111 1111 1111 1111 1111 1111. 也就是 0xffffffff。这个显然不是我们想要的。虽然在十进制数值的角度来说应该这个值才是-1.但我们首先要注意到这里我们不是用的十进制。
那么也就是说,我们要的只是转换后的低八位的值。所以我们用 0xff 对转换的数字进行与操作。这样我们就能把低八位的数值保存下来而不受Java转换的影响。代码如下:
return (((int)byteList[5] & 0xff) << 24)
| ((int)(byteList[4] & 0xff) << 16)
| ((int)(byteList[3] & 0xff) << 8)
| ((int)(byteList[2] & 0xff));
读取BMP图像size的时候与操作和左移的原因的更多相关文章
- OpenCV 编程简单介绍(矩阵/图像/视频的基本读写操作)
PS. 因为csdn博客文章长度有限制,本文有部分内容被截掉了.在OpenCV中文站点的wiki上有可读性更好.而且是完整的版本号,欢迎浏览. OpenCV Wiki :<OpenCV 编程简单 ...
- BMP图像数据格式详解
一.简介 BMP(Bitmap-File)图形文件是Windows采用的图形文件格式,在Windows环境下运行的所有图象处理软件都支持BMP图象文件格式.Windows系统内部各图像绘制操作都是以B ...
- 【转】BMP图像文件格式
5.1 BMP图像文件格式 BMP图像文件格式是游戏中常用的图像资源文件格式,BMP图像文件起源早,程序员对BMP都比较熟悉,再加上BMP格式简单,读取和写入非常容易实现,所以无论Windows的还 ...
- VTK读取序列化图像
vtk获取内存中图像数据 原文链接:http://blog.csdn.net/zmy3376365/article/details/7717721 内存中有段图片数据 ,使用VTK来读入,然后就可以 ...
- 远程控制编写之屏幕传输 MFC实现 屏幕截图 发送bmp数据 显示bmp图像
远程控制编写之屏幕传输 MFC实现 屏幕截图 发送bmp数据 显示bmp图像: 一 : 首先要了解bmp图像的结构 详情请看我转载的一篇文章http://blog.csdn.net/hnust_x ...
- [转]opengl入门例题(读取bmp图片,并显示)
#include<gl/glut.h> #define FileName "bliss.bmp" static GLint imagewidth; static GLi ...
- Halcon一日一练:读取文件目录图像的三种方法
第一种方法: 读了一个单一图像: read_image(Image,'fabrik') 这种方式可以快速的读取软件自身携带的库图像文件,系统设定了库图像映像文件的快速读取方式,我们也可以通过绝对地址的 ...
- 使用C#版本GDAL读取复数图像
GDAL的C#版本虽然在很多算法接口没有导出,但是在读写数据中的接口基本上都是完全导出了.使用ReadRaster和WriteRaster方法来进行读写,同时对这两个方法进行了重载,对于常用的数据类型 ...
- DB2读取CLOB字段-was报错:操作无效:已关闭 Lob。 ERRORCODE=-4470, SQLSTATE=null
DB2读取CLOB字段-was报错:操作无效:已关闭 Lob. ERRORCODE=-4470, SQLSTATE=null 解决方法,在WAS中要用的数据源里面配置连个定制属性: progressi ...
随机推荐
- 2011 Multi-University Training Contest 8 - Host by HUST
Rank:56/147. 开场看B,是个线段树区间合并,花了2hour敲完代码...再花了30min查错..发现push_down有问题.改了就AC了. 然后发现A过了很多人.推了个公式,发现是个分段 ...
- P1491 集合位置
题目描述 每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家都要玩的痛快.还记得心语和花儿在跳舞机上的激情与释放,还记得草草的投篮技艺是如此的高超,还记得狗狗的枪法 ...
- [CF452E]Three strings
题目大意:给你三个字符串$A,B,C$,令$L=min(|A|,|B|,|C|)$,对每个$i\in[1,L]$,求出符合$A_{[a,a+i)}=B_{[b,b+i)}=C_{[c,c+i)}$的三 ...
- PyTorch为何如此高效好用?
C/C++中 Python 扩展对象的简介 你可能知道可以借助 C/C++扩展 Python,并开发所谓的「扩展」.PyTorch 的所有繁重工作由 C/C++实现,而不是纯 Python.为了定义 ...
- BZOJ3173:[TJOI2013]最长上升子序列 & HDU3564:Another LIS——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=3173 http://acm.hdu.edu.cn/showproblem.php?pid=3564 ...
- UVALive.2995 Image Is Everything (思维题 三维坐标转换)
UVALive.2995 Image Is Everything (思维题 三维坐标转换) 题意分析 这题实在是没思路,就照着打了一遍,把不理解的地方,写了注释. #include <iostr ...
- 使用springcloud的feign调用服务时出现的错误:关于实体转换成json错误的介绍
http://blog.csdn.net/java_huashan/article/details/46428971 原因:实体中没有添加无参的构造函数 fastjson的解释: http://www ...
- idea一些文件如.xml 文件搜索不到的解决方法
- mysql中的case when 与if else
大神说:在sql中,能用if else 就不用case when 下面来看看,具体为什么,没有搞清楚,如果有大神知道的提供下资料: Mysql的if既可以作为表达式用,也可在存储过程中作为流程控制 ...
- CentOS 下安装 LEMP 服务(nginx、MariaDB/MySQL 和 php)
转载自:https://linux.cn/article-4314-1.html 编译自:http://xmodulo.com/install-lemp-stack-centos.html 作者: D ...