java读取bmp位图


BMP由四部分组成 ,位图文件头 , 位图信息头 ,  颜色 , 图像数据区

 

BMP图片是三个字节为一个颜色保存,将字节拼接为int需要使用位移来做

 

位图文件头 (12个字节):

 0000-0001:文件标识,为字母ASCII码“BM”,42 4D。

0002-0005:整个文件大小,单位字节。
0006-0009:这个位置的数字是被微软保留的
000A-000D:记录图像数据区的起始位置。从文件开始到位图数据(bitmap data)之间的偏移量。 

位图信息头()
000E-0011:图像描述信息块的大小
0012-0015:图像宽度。以像素为单位。
0016-0019:图像高度。以像素为单位。
001A-001B:图像的plane总数(恒为1)。
001C- 001D:记录像素,也就是颜色。1 - Monochrome bitmap,4 - 16 color bitmap,8 - 256 color bitmap,F - 16位位图,18 - 24bit (true color) bitmap,20 - 32位位图。

001E-0021:数据压缩方式(数值位0:不压缩;1:8位压缩;2:4位压缩;3:Bitfields压缩)。
0022-0025:图像区数据的大小。单位字节,该数必须是4的倍数。
0026-0029:水平每米有多少像素,在设备无关位图(.DIB)中,每字节以00H填写。
002A-002D:垂直每米有多少像素,在设备无关位图(.DIB)中,每字节以00H填写。
002E-0031:此图像所用的颜色数。

0032-0035:指定重要的颜色数。当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要。

 

读取图片是注意跳过前18个字节,然后读出图片大小,图像数据区的大小与图片实际尺寸可能存在不一致,因为图片数据区字节数必须是4的倍数,所以后面可能有补零,需要舍弃。

其次,在通过读取四字节图片大小转化为int时需要注意byte值应该与0xff相与,否则可能出现负数,因为java采用补码存储数据。

package CZG;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.awt.Color;

public class BMPReader {

    /**
     * @param args
     * @return
     * @throws IOException
     */

    public static int[][] ReadBMPPic(String src) throws IOException
    {
        FileInputStream fis=new FileInputStream(src);
        BufferedInputStream bis=new BufferedInputStream(fis);
            
        //丢掉文件头信息
        bis.skip(18);
        
        //获取长度与宽度
        byte[] b1=new byte[4];
        bis.read(b1);
        byte[] b2=new byte[4];
        bis.read(b2);
        
        int Width=byte2Int(b1);
        int Height=byte2Int(b2);
        System.out.println("Hight:"+Height+" Width:"+Width);
        
        //因为bmp位图的读取顺序为横向扫描,所以应把数组定义为int[Height][Width]
        int[][] data=new int[Height][Width];
        int skipnum=0;
        
        //bmp图像区域的大小必须为4的倍数,而它以三个字节存一个像素,读的是偶应当跳过补上的0
        if(Width*3%4!=0)
        {
            skipnum=4-Width*3%4;
        }
        System.out.println(skipnum);
        
        bis.skip(28);
        
        for(int i=0;i<data.length;i++)
        {
            for(int j=0;j<data[i].length;j++)
            {
                int red=bis.read();
                int green=bis.read();
                int blue=bis.read();
            }
            if(skipnum!=0)
            {
                bis.skip(skipnum);
            }
        }
        
        bis.close();
        return data;
    }
    private static int byte2Int(byte[] b) throws IOException {
        // TODO Auto-generated method stub
        int num=(b[3]&0xff<<24)|(b[2]&0xff)<<16|(b[1]&0xff)<<8|b[0]&0xff);
        return num;
    }
    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        ReadBMPPic("LennaBinary.bmp");
    }

}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM