博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java读取bmp位图
阅读量:5096 次
发布时间:2019-06-13

本文共 2374 字,大约阅读时间需要 7 分钟。

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");
    }
}

转载于:https://www.cnblogs.com/NKCZG/p/4369832.html

你可能感兴趣的文章
js 过滤敏感词
查看>>
poj2752 Seek the Name, Seek the Fame
查看>>
软件开发和软件测试,我该如何选择?(蜗牛学院)
查看>>
基本封装方法
查看>>
生活大爆炸之何为光速
查看>>
[Typescript] Specify Exact Values with TypeScript’s Literal Types
查看>>
Illustrated C#学习笔记(一)
查看>>
理解oracle中连接和会话
查看>>
Scrapy实战篇(三)之爬取豆瓣电影短评
查看>>
HDU 5510 Bazinga KMP
查看>>
[13年迁移]Firefox下margin-top问题
查看>>
Zookeeper常用命令 (转)
查看>>
Enterprise Library - Data Access Application Block 6.0.1304
查看>>
重构代码 —— 函数即变量(Replace temp with Query)
查看>>
Bootstrap栅格学习
查看>>
程序员的数学
查看>>
聚合与组合
查看>>
洛谷 P2089 烤鸡【DFS递归/10重枚举】
查看>>
我眼中的技术地图
查看>>
lc 145. Binary Tree Postorder Traversal
查看>>