在读取一个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的时候与操作和左移的原因的更多相关文章

  1. OpenCV 编程简单介绍(矩阵/图像/视频的基本读写操作)

    PS. 因为csdn博客文章长度有限制,本文有部分内容被截掉了.在OpenCV中文站点的wiki上有可读性更好.而且是完整的版本号,欢迎浏览. OpenCV Wiki :<OpenCV 编程简单 ...

  2. BMP图像数据格式详解

    一.简介 BMP(Bitmap-File)图形文件是Windows采用的图形文件格式,在Windows环境下运行的所有图象处理软件都支持BMP图象文件格式.Windows系统内部各图像绘制操作都是以B ...

  3. 【转】BMP图像文件格式

    5.1  BMP图像文件格式 BMP图像文件格式是游戏中常用的图像资源文件格式,BMP图像文件起源早,程序员对BMP都比较熟悉,再加上BMP格式简单,读取和写入非常容易实现,所以无论Windows的还 ...

  4. VTK读取序列化图像

    vtk获取内存中图像数据 原文链接:http://blog.csdn.net/zmy3376365/article/details/7717721 内存中有段图片数据  ,使用VTK来读入,然后就可以 ...

  5. 远程控制编写之屏幕传输 MFC实现 屏幕截图 发送bmp数据 显示bmp图像

    远程控制编写之屏幕传输  MFC实现  屏幕截图 发送bmp数据 显示bmp图像: 一 : 首先要了解bmp图像的结构 详情请看我转载的一篇文章http://blog.csdn.net/hnust_x ...

  6. [转]opengl入门例题(读取bmp图片,并显示)

    #include<gl/glut.h> #define FileName "bliss.bmp" static GLint imagewidth; static GLi ...

  7. Halcon一日一练:读取文件目录图像的三种方法

    第一种方法: 读了一个单一图像: read_image(Image,'fabrik') 这种方式可以快速的读取软件自身携带的库图像文件,系统设定了库图像映像文件的快速读取方式,我们也可以通过绝对地址的 ...

  8. 使用C#版本GDAL读取复数图像

    GDAL的C#版本虽然在很多算法接口没有导出,但是在读写数据中的接口基本上都是完全导出了.使用ReadRaster和WriteRaster方法来进行读写,同时对这两个方法进行了重载,对于常用的数据类型 ...

  9. DB2读取CLOB字段-was报错:操作无效:已关闭 Lob。 ERRORCODE=-4470, SQLSTATE=null

    DB2读取CLOB字段-was报错:操作无效:已关闭 Lob. ERRORCODE=-4470, SQLSTATE=null 解决方法,在WAS中要用的数据源里面配置连个定制属性: progressi ...

随机推荐

  1. BZOJ4710 JSOI2011分特产(容斥原理+组合数学)

    显然可以容斥去掉每人都不为空的限制.每种物品分配方式独立,各自算一个可重组合乘起来即可. #include<iostream> #include<cstdio> #includ ...

  2. 响应式布局(rem布局),使用JS动态设置fontsize

    var cw = document.documentElement.clientWidth; if (cw > 1920) { cw = 1920; } document.getElements ...

  3. Necklace - CF613C

    Ivan wants to make a necklace as a present to his beloved girl. A necklace is a cyclic sequence of b ...

  4. [USACO16OPEN]钻石收藏家Diamond Collector

    由于相差不超过k才可以放在一起,要判断不超过k这个条件,显然我们需要排序 首先我们需要一个f数组,f[i]意义看代码开头注释, 假设我们可以选择的某一个区间是a[l]~a[r](已排序且最优(最长的意 ...

  5. 洛谷3934:Nephren Ruq Insania——题解

    https://www.luogu.org/problemnew/show/P3934 题面自己读吧(滑稽. 看到这道题就能够想到BZOJ4869:[SHOI2017]相逢是问候我们曾经用过的哲学扩展 ...

  6. [APIO2017]商旅

    link 这题卡我精度,调了一晚上才调对,因为没有想到图还可以不连通 其实可以预处理出好多东西,距离($dis(u,v)$),买卖物品(从$u$到$v$买卖物品的最大利润,例($max{S_{u,i} ...

  7. 【逆序对相关/数学】【P1966】【NOIP2013D1T2】 火柴排队

    传送门 Description 涵涵有两盒火柴,每盒装有 $n$ 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为:$ \sum ...

  8. 【枚举】 最大子矩阵(I)

    题注:最大子矩形问题的解决办法最初由中国国家集训队王知昆前辈整理并发表为论文,在此说明并感谢. Definition 给你一个大矩形,里面有一些障碍点,求一个面积最大的矩形,满足该矩形在大矩形内部且该 ...

  9. 高效率JavaScript代码的编写技巧

    使用DocumentFragment优化多次append 添加多个dom元素时,先将元素append到DocumentFragment中,最后统一将DocumentFragment添加到页面.该做法可 ...

  10. Ubuntu安装CUDA9.0 + cuDNN

    本篇文章是基于安装CUDA 9.0的经验写,CUDA9.0目前支持Ubuntu16.04和Ubuntu17.04两个版本,如下图所示(最下面的安装方式我们选择第一个,即runfile方式): 下载链接 ...