读取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 ...
随机推荐
- Qt——树结点的搜索
一.Qt中的树 平时我们经常使用树的结构来组织和展示数据,比如文件系统等—— 在Qt中,我们可以使用Qt提供的便捷的QTreeWidget类,利用该类的接口,轻松地将已有数据显示在树中. 除此之外,还 ...
- P1491 集合位置
题目描述 每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家都要玩的痛快.还记得心语和花儿在跳舞机上的激情与释放,还记得草草的投篮技艺是如此的高超,还记得狗狗的枪法 ...
- poj2018——Best Cow Fences
Description Farmer John's farm consists of a long row of N (1 <= N <= 100,000)fields. Each fie ...
- 【luogu2181】对角线
首先由于不会有三条对角线交于一点,所以过某一个交点有且只能有2条对角线 而这两条对角线实质上是确定了4个顶点(也可以看做是一个四边形的两条对角线交于一点,求四边形的数量). 因此我们只需要确定4个顶点 ...
- BZOJ3437 小P的牧场 【斜率优化dp】
3437: 小P的牧场 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1502 Solved: 836 [Submit][Status][Disc ...
- bzoj1057: [ZJOI2007]棋盘制作(悬线法)
题目要求纵横坐标和奇偶性不同的点取值不同,于是我们把纵横坐标和奇偶性为1的点和0的点分别取反,就变成经典的最大全1子矩阵问题了,用悬线法解决. #include<iostream> #in ...
- HBase工具之监控Region的可用和读写延时状况
1.介绍HBase集群上region数目由于业务驱动而越来越多,由于服务器本身,网络以及hbase内部的一些不确定性bug等因素使得这些region可能面临着不可用或响应延时情况.通过对region的 ...
- Android之简易音乐播发器
布局主要代码之ListView: <span style="font-size:14px;"> <ListView android:id="@+id/m ...
- .net 跨域 问题解决
参考地址:http://www.cnblogs.com/moretry/p/4154479.html 在项目上面使用 Nuget 搜索 microsoft.aspnet.webapi.cors 直接下 ...
- redis初试Not all 16384 slots are covered by nodes
按照这里的步骤玩redis集群,http://www.redis.cn/topics/cluster-tutorial.html ./src/redis-trib.rb create --replic ...