JAVA BMP解码 超详细解释_第1页
JAVA BMP解码 超详细解释_第2页
JAVA BMP解码 超详细解释_第3页
JAVA BMP解码 超详细解释_第4页
JAVA BMP解码 超详细解释_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

./首先,对于BMP格式的图片大家都不感觉到陌生吧。简单的说明下:

BMP是一种与硬件设备无关的图像文件格式,使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。BMP文件的图像深度可选lbit、4bit、8bit及24bit。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。

由于BMP文件格式是Windows环境换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都支持BMP图像格式。要解析文件,就必须知道他的文件结构文件结构组成典型的BMP图像文件由四部分组成:1:

位图文件头数据结构,它包含BMP图像文件的类型、显示容等信息;2:位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息;3:调色板,这个部分是可选的,有些位图需要调色板,有些位图,比如真彩色图〔24位的BMP就不需要调色板;4:位图数据,这部分的容根据BMP位图使用的位数不同而不同,在24位图中直接使用RGB,而其他的小于24位的使用调色板中颜色索引值。

对应的数据结构1.BMP文件头<14字节>BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。其结构定义如下:IntbfType;

//

位图文件的类型,必须为'B''M'两个字母<0-1字节>IntbfSize;

//

位图文件的大小,以字节为单位<2-5字节>usignedshort

bfReserved1;

//

位图文件保留字,必须为0<6-7字节>usignedshort

bfReserved2;

//

位图文件保留字,必须为0<8-9字节>IntbfOffBits;

//

位图数据的起始位置,以相对于位图<10-13字节>IntbfOffBits;//

文件头的偏移量表示,以字节为单位2:位图信息头<40字节>BMP位图信息头数据用于说明位图的尺寸等信息。IntSize;

//

本结构所占用字节数<14-17字节>Intimage_width;

//

位图的宽度,以像素为单位<18-21字节>intimage_heigh;

//

位图的高度,以像素为单位<22-25字节>IntPlanes;

//

目标设备的级别,必须为1<26-27字节>intnbiBitCount;//

每个像素所需的位数,必须是1<双色>,<28-29字节>//

4<16色>,8<256色>或24<真彩色>之一Int

biCompression;

//

位图压缩类型,必须是

0<不压缩>,<30-33字节>//

1<BI_RLE8压缩类型>或2<BI_RLE4压缩类型>之一IntnSizeImage;

//

位图的大小,以字节为单位<34-37字节>IntbiXPelsPerMeter;

//

位图水平分辨率,每米像素数<38-41字节>Int

biYPelsPerMeter;

//

位图垂直分辨率,每米像素数<42-45字节>Int

biClrUsed;//

位图实际使用的颜色表中的颜色数<46-49字节>Int

biClrImportant;//

位图显示过程中重要的颜色数<50-53字节>3:颜色表颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。class

RGBQUAD{byte

rgbBlue;//

蓝色的亮度<值围为0-255>byte

rgbGreen;

//

绿色的亮度<值围为0-255>byte

rgbRed;

//

红色的亮度<值围为0-255>byte

rgbReserved;//

保留,必须为0}颜色表中RGBQUAD结构数据的个数有biBitCount来确定:当biBitCount=1,4,8时,分别有2,16,256个表项;当biBitCount=24时,没有颜色表项。位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:class

BITMAPINFO{BITMAPINFOHEADER

bmiHeader;

//

位图信息头RGBQUAD

bmiColors[1];

//

颜色表}

4:位图数据位图数据记录了位图的每一个像素值,记录顺序是在扫描行是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数:当biBitCount=1时,8个像素占1个字节;当biBitCount=4时,2个像素占1个字节;当biBitCount=8时,1个像素占1个字节;当biBitCount=24时,1个像素占3个字节;Windows规定一个扫描行所占的字节数必须是4的倍数<即以long为单位>,不足的以0填充,具体数据举例:如某BMP文件开头:424D

4690

0000

0000

0000

4600

0000

2800

0000

8000

0000

9000

0000

0100*1000

0300

0000

0090

0000

A00F

0000

A00F

0000

0000

0000

0000

0000*00F8

E007

1F00

0000*02F1

84F1

04F1

84F1

84F1

06F2

84F1

06F2

04F2

86F2

06F2

86F2

86F2

BMP文件可分为四个部分:位图文件头、位图信息头、彩色板、图像数据阵列,在上图中已用*分隔。

猥琐分割线比方说,我们就可以做一个BMP图片的查看器1、打开BMP文件时,我们这里选择使用dataInputstream

读取一个最常见的24位真彩色BMP图片Java代码//

创建文件输入流java.io.FileInputStream

fis

=

new

java.io.FileInputStream<path>;

//

将文件流包装成一个可以写基本数据类型的输出流

java.io.DataInputStream

dis

=

new

java.io.DataInputStream<fis>;

2、读入BMP头文件的基本信息Java代码int

bflen=14;

byte

bf[]=new

byte[bflen];

dis.read<bf,0,bflen>;

//读取14字节BMP文件头

因为看到了BMP头文件中没有说明显示图片重要的信息,我只是开一个BF的数组,把头文件信息读取了出来,不做任何的处理。3、读入位图信息头Java代码int

bilen=40;

byte

bi[]=new

byte[bilen];

dis.read<bi,0,bilen>;//读取40字节BMP信息头

//

获取一些重要数据

image_width=ChangeInt<bi,7>;

//源图宽度

System.out.println<"宽:"+image_width>;

image_heigh=ChangeInt<bi,11>;

//源图高度

System.out.println<"高:"+image_heigh>;

//位数

int

nbitcount=<<<int>bi[15]&0xff><<8>

|

<int>bi[14]&0xff;

System.out.println<"位数:"+nbitcount>;

//源图大小

int

nsizeimage=ChangeInt<bi,23>;

System.out.println<"源图大小:"+nsizeimage>;

由位图信息头中我们也可以看出来,要显示图片,重要的信息也就只有几个,其他都是一些不重要的,我们直接忽略掉。因为我是直接读取40位的信息头所以要将一些byte转为int

即ChangeInt即

4个byte

>

一个intJava代码//转成int

public

int

ChangeInt<byte[]

bi,int

start>{

return

<<<int>bi[start]&0xff><<24>

|

<<<int>bi[start-1]&0xff><<16>

|

<<<int>bi[start-2]&0xff><<8>

|

<int>bi[start-3]&0xff;

}

因为24为的没有颜色表,所以我们直接读位图数据

最后,最关键的就是,读取位图数据Java代码public

void

showRGB24<DataInputStream

dis>

throws

IOException{

this.setTitle<path>;

//弹出一个图片的窗口一个大小

this.setSize<image_width,

image_heigh>;

this.setResizable<false>;

this.setVisible<true>;

g=this.getGraphics<>;

if<!<image_width*3

%

4==0>>{//图片的宽度不为0

skip_width

=4-image_width*3%4;

}//判断是否后面有补0

的情况

//装载RGB颜色的数据数组

imageR

=

new

int[image_heigh][image_width];

imageG

=

new

int[image_heigh][image_width];

imageB

=

new

int[image_heigh][image_width];

//按行读取

如果H,W为正则倒着来

for

<int

h=image_heigh-1;h>=0;h-->{

for

<int

w=0;w<image_width;w++>{

/

读入三原色

int

blue

=

dis.read<>;

int

green

=

dis.read<>;

int

red

=

dis.read<>;

imageB[h][w]=blue;

imageG[h][w]=green;

imageR[h][w]=red;

if<w==0>{//跳过补0项

System.out.println<dis.skipBytes<skip_width>>;

}

}

}

repaint<>;

}

关键就是在于

位图是否有补0有则要跳过,没有就直接读,不然显示出来的BMP图像会倾斜。即注释掉这句话得到的效果Java代码if<w==0>{

System.out.println<dis.skipBytes<skip_width>>;

}

最后paint<>中显示就可以看见图片了Java代码

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论