BMP图像文件小结

一.BMP图像文件

BMP是一种与硬件设备无关的图像文件格式,使用非常广。它采用位映射存储格式。通常我们看到的bmp图像文件一般都比较大,占用很大的空间。因为除了位像深度可选以外,其他不采用任何压缩。Bmp文件存储数据时,图像的扫描方式是按从左到右,从下到上的顺序。所以读取时,我们也要注意这个问题。BMPWindows环境中交换与图有关的数据的一种标准,在Windows环境中运行的图形图像软件都支持BMP图像格式。

 

典型的BMP图像文件由四部分组成:文件头,图像参数,调色板,位图数据。

简单介绍下这四个部分。

1:文件头,占14个字节。它包含BMP图像文件的类型、内容尺寸和起始偏移量等信息。

位图文件类型,占两个字节,第一个字节为字母'B',第二个字节为字母'M'(1-2字节) 位图文件的大小,以字节为单位(3-6字节)。还有四个字节的保留字

位图数据部分相对于文件首的起始偏移量,如果知道文件头了,这样就可以直接知道图像的颜色保存在那个位置了。

2:图像参数,它包含图像的宽、高、压缩方法,以及颜色定义等信息

3:调色板(可选部分)

bpp:表示图像像素值的位数叫做图像的像素深度,又称为位/像素(BPP)。

bpp较小的位图需要调色板;有些位图,比如24bpp(真彩色)图就不需要调色板;

41.位图数据(一般为40个字节)

这部分的内容因位图实际像素位数和编码格式而不同,在真彩位图中直接使用RGB真彩色值;而有调色板的位图则使用调色板中颜色索引值。

每个像素所需的位数,必须是1(双色)4(16)8(256)24(真彩色)之一,(29-30字节)

位图数据包括:位图的大小,水平分辨率和垂直分辨率。以及位图实际使用的颜色表中的颜色数和位图显示过程中重要的颜色数。

 

2.位图数据的读取(读取的方法有点特别)

.每行的字节数必须是4的倍数,如果不是,则需要后面用0补齐。

BMP位图数据的存放是从下到上,从左到右的。故我们也需要先读最后一行,读完后在读倒数第二行。

虽然说,bmp图像文件一般有四个部分,但在实际过程中,我们如果知道图像的长和高,以及每一点的颜色也可以将文件中的图片重绘出来。

如图:

 

 

 

package bmp;

import java.awt.Color;
import java.awt.Graphics;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

import javax.swing.JFrame;

public class bmpTest extends JFrame{
	private int image_width;//图片的长和高
	private int image_heigh;
	Graphics  g;      //画布对象
    int blue,green,red;  
	int skip_width;   //跳过的项数
	
	int[][] imageR,imageG,imageB; //RGB的三个分值
	static String path="D:\\1000\\西北风光.bmp";
	/**
	 * 程序入口
	 * @param args
	 */
	public  static void  main(String [] args){
		 bmpTest BT=new bmpTest();
		 BT.read(path);
	}
	public void read(String path){
		try{
			//创建文件读取流
			FileInputStream  fis=new FileInputStream(path);
			BufferedInputStream  bis=new BufferedInputStream(fis);//将文件包装成一个普通数据类型的缓冲输出流
			
			 int bflen = 14;
			 byte[] bf = new byte[bflen];
			 bis.read(bf, 0, bflen);// 读取14字节的BMP文件头
			 
			 int bilen=40;
			 byte[]  bi=new byte[bilen];
			 bis.read(bi,0,bilen);   //读取40个字节的位图信息
			 image_width=ChangeInt(bi,7);  //原图宽度
			 image_heigh=ChangeInt(bi,11);   //原图高度

			 showRGB24(bis);    //读取位图数据
			
			 fis.close();  //关闭流
		     bis.close();
		     showUI();//调用窗口实现的方法
     	}
		
		catch(Exception e){
			e.printStackTrace();
		} 
	}
	/**
	 * 数据转换的方法
	 * @param bi 需要转换的数据存放的数组
	 * @param start 从数组的哪个位置开始转换
	 * @return  用一个int型返回转换好的数据
	 */
	public int ChangeInt(byte[] bi,int start){//将四个byte型的数据从低到高转成一个int型的数据
		return   (((int)bi[start]&0xff)<<24)|(((int)bi[start-1]&0xff)<<16)|(((int)bi[start-2]&0xff)<<8)|(int)bi[start-3]&0xff;
		
	}
	public void showRGB24(BufferedInputStream  dis)throws IOException{
		  if(!(image_width*3%4==0)){
			  skip_width=4-image_width*3%4;
		   }
		imageR=new int[image_heigh][image_width];//创建三个二维数组分别用来存放 颜色的R,G,B值
		imageG=new int[image_heigh][image_width];
		imageB=new int[image_heigh][image_width];
		 for (int h = image_heigh - 1; h >= 0; h--) {
			   for (int w = 0; w < image_width; w++) {
			     blue = dis.read();// 先读取出蓝色
			     green = dis.read();// 读取出绿色
			     red = dis.read();   // 读取的是红色
			     imageR[h][w] = red;
			     imageG[h][w] = green;
			     imageB[h][w] = blue;
			  
			     if (w ==image_width-1) {
			     // 跳过补0项
			      dis.skip(skip_width);
			    }
			   }
		 }
	}
	public void showUI(){
		//设置窗体的一些属性
		this.setTitle("(bmp)西北风光图片");//标题
		this.setSize(image_width,image_heigh); //大小
		this.setDefaultCloseOperation(3);  //当点击关闭按钮时,使程序退出
		this.setResizable(false);  //不能改变大小
		this.setVisible(true);    //使窗体实现
		g=this.getGraphics();    //获得窗体的画布对象
		repaint();               //重绘图片
	}
	/**
	 * 重写paint方法
	 */
	public void paint(Graphics g){
		super.paint(g);
		for(int h=0;h<image_heigh;h++){
			for(int w=0;w<image_width;w++){
				g.setColor(new Color(imageR[h][w],imageG[h][w],imageB[h][w]));//设置每个像素点的颜色
				g.drawLine(w,h,w,h);                        //重画每一个点
			}
		}
	}
}

 

 

遇到的问题:

在测试的时候,开始总是出现OutOfMemoryError异常,完全崩溃,看不懂啊!后来不知道怎么搞的,就将图片的格式换了换。才知道,是我只是将开始的jpg图片的后缀改了,但是它并不是bmp格式的图像。才终于解决这个问题。

其次,就是,在将文件包装成一个普通数据类型的输出流时,我使用的是DataInputStream流,以致图片重绘的时候,出现图像扭曲闪屏现象。在这里,使用缓冲流好些,不会出现这种情况。

 

其实,这次的学习给我留下了深刻的印象。因为这次的学习是由我们班的同学组织学习的。哎。。。一定要好好像他学习啊!!!

 

   二.下面是几种常见的图像文件格式:

1.JPEG格式

  JPEG是常见的一种图像格式,JPEG文件的扩展名为.jpg.jpeg

 JPEG 是与平台无关的格式,支持最高级别的压缩,其压缩技术十分先进,它用有损压缩方式去除冗余的图像和彩色数据,获取得极高的压缩率的同时能展现十分丰富生动的图像,所以说JPEG是一种很灵活的格式,但这种压缩是有损耗的。文件大小是以图像质量为代价的。JPEG 不适用于所含颜色很少、具有大块颜色相近的区域或亮度差异十分明显的较简单的图片。

2.TIFF:标记图像文件格式

TIFF 以任何颜色深度存储单个光栅图像。由于TIFF格式结构较为复杂,兼容性较差,因此有时你的软件可能不能正确识别TIFF文件(现在绝大部分软件都已解决了这个问题)。目前在MacPC机上移植TIFF文件也十分便捷,因而TIFF现在也是微机上使用最广泛的图像文件格式之一。

TIFF 支持可选压缩,但不适用于在 Web 浏览器中查看。

 

3.GIF格式

  GIF格式的特点是压缩比高,磁盘空间占用较少,被广泛应用。

  GIF的缺点,即不能存储超过256色的图像。尽管如此,这种格式仍在网络上大行其道应用,这和GIF图像文件短小、下载速度快、可用许多具有同样大小的图像文件组成动画等优势是分不开的。

4.PNG格式

  PNGPortableNetworkGraphics)是一种新兴的网络图像格式。

  PNG是目前保证最不失真的格式,它汲取了GIFJPG二者的优点,存贮形式丰富,兼有GIFJPG的色彩模式;它能把图像文件压缩到极限以利于网络传输,但又能保留所有与图像品质有关的信息,因为PNG是采用无损压缩方式来减少文件的大小,这一点与牺牲图像品质以换取高压缩率的JPG有所不同;它的另一特点是显示速度很快,只需下载1/64的图像信息就可以显示出低分辨率的预览图像。而且PNG同样支持透明图像的制作,透明图像在制作网页图像的时候很有用,我们可以把图象背景设为透明,用网页本身的颜色信息来代替设为透明的色彩,这样可让图像和网页背景很和谐地融合在一起。

  PNG的缺点是不支持动画应用效果

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值