当前位置: 代码迷 >> Java相关 >> 读取bmp文件时的位操作有关问题
  详细解决方案

读取bmp文件时的位操作有关问题

热度:8811   发布时间:2013-02-25 21:44:13.0
读取bmp文件时的位操作问题
Java code
            FileInputStream stream = new FileInputStream(filePath);                        byte bh[] = new byte[bfhead];            byte bi[] = new byte[bfinfo];            stream.read(bh, 0, bfhead);            stream.read(bi, 0, bfinfo);                        // 因为数据是以小端方式存储的,所以高地址存放的是高位数据            width = ( ( (int) bi[7] & 0xff) << 24) //width of source file            | ( ( (int) bi[6] & 0xff) << 16)            | ( ( (int) bi[5] & 0xff) << 8)            | (int) bi[4] & 0xff;            height = ( ( (int) bi[11] & 0xff) << 24) //heigth of source file            | ( ( (int) bi[10] & 0xff) << 16)            | ( ( (int) bi[9] & 0xff) << 8)            | (int) bi[8] & 0xff;

以上代码中width, height在之前已经定义为int类型。数组bi中存放的是位图信息头40个字节的数据。
为什么在取bi中4个字节的位图宽度和高度时每个字节都要进行“& 0xff”操作?求解释


------解决方案--------------------------------------------------------
主要原因是java的byte类型是有符号的,不进行&0xff操作的话,就会得到不正确的数。

假设位图高为1000,其16进制表示为3e8. 存放到4个字节里是 bi[7]=0x00;bi[6]=0x00;bi[5]=0x03;bi[4]=0xe8(232). 把他们组合起来,能够得到1000。
java 里还原这个整数,实际上是把这4个字节的数,组合起来,形成一个int型整数。
对于bi[7],bi[6],bi[5],因为他们的范围小于127,都是正整数(符号位为0)。即使不进行&0xff操作,也正常。
但对于bi[4],不处理就有问题了!java 读这个字节时,java把它认为是个负数,是-24! (实际上是232)看看变成int型的情况,(int)bi[4]:
变成int型,占4个子节,实际上还是-24,其二进制表示是:
1111 1111 1111 1111 1111 1111 1110 1000,显然这个数不是我们要的232,那怎么办呢,用位与运算最好解决了。把它和0xff(二进制是0000 0000 0000 0000 0000 0000 1111 1111)进行与运算,最后就得到了,
0000 0000 0000 0000 0000 0000 1110 1000,即10进制的232。把代表负号的高位都去掉了,得到了0000 0000 0000 0000 0000 0000 1110 1000。

我说的不一定清楚,楼主参考一下。
  相关解决方案