java读取bmp图片像素数据_java读取bmp位图

本文介绍如何使用Java读取BMP图像的像素数据,包括解析位图文件头、位图信息头,并详细说明了读取过程中的注意事项,如跳过前18个字节,处理字节到整数转换时的负数问题,以及处理图像数据区可能存在的补零字节。
摘要由CSDN通过智能技术生成

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

{

for(int j=0;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");

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值