`
GLC
  • 浏览: 110819 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

BMP格式简单总结

 
阅读更多
BMP文件总结
(诸多错误、谢谢指点
1、BMP文件结构由四部分组成
      a、位图文件  头数据结构,包括BMP图形

文件的类型,显示内容等。
private int size;// 位图信息头所占用字节



      b、位图信息数据结构   包含BMP图像的

宽,高,压缩方法以及定义颜色等信息
         
 private int image_width;// 位图的宽度

private int image_height;// 位图的高度
private int image_size;// 位图的

大小
private int biXpelsPerMeter;// 水

平分辨率
private int biYpelsPerMeter;// 垂

直分辨率
private int biBitCount = 24;// 每

个像素所需的位数(1双色,4是16色,8是256色

,之一)

      c、调色板,有些需要有些也不需要

      d、位图数据  这根据BMP位图使用位数不同而不同;在24位图中直接使用RGB
        
private int Planes = 1;// 目标设备的级别,必须为1(26-27字节)

private int biClrUsed;// 位图实际使用的颜色中的颜色数
private int biClrImportant;// 位图显式过程中重要的颜色数

2、BMP数据结构
    a、BMP文件头、包含文件的类型、文件大小、位图起始位置
//存储位图文件的类型
bfHead[0]='B';

bfHead[1]='M'; 
    b、位图信息头:用于说明位图的尺寸等信息
int size;// 位图信息头所占用字节数
int image_width;// 位图的宽度
int image_height;// 位图的高度
int image_size;// 位图的大小
int biXpelsPerMeter;// 水平分辨率
int biYpelsPerMeter;// 垂直分辨率
biBitCount = 24;// 每个像素所需的位数(1双色,4是16色,8是256色,之一)

Planes = 1;// 目标设备的级别,必须为1(26-27字节)
biClrUsed;// 位图实际使用的颜色中的颜色数
biClrImportant;// 位图显式过程中重要的颜色数


    c、颜色表:用于说明图中的颜色、
    d、位图数据:记录位图每一个像素值,记录顺序是在扫描从左到右、从下到上
其实现过程如下:

1、声明文件的信息头


private int size;// 位图信息头所占用字节数
private int image_width;// 位图的宽度
private int image_height;// 位图的高度
private int image_size;// 位图的大小
private int biXpelsPerMeter;// 水平分辨率
private int biYpelsPerMeter;// 垂直分辨率
private int biBitCount = 24;// 每个像素所需的位数(1双色,4是16色,8是256色,之一)

private int Planes = 1;// 目标设备的级别,必须为1(26-27字节)
private int biClrUsed;// 位图实际使用的颜色中的颜色数
private int biClrImportant;// 位图显式过程中重要的颜色数

private byte[] info = new byte[40];// 定义数组,用于存储信息头的数据
2、文件宽、高保存:
public InfoHead_BMP(int image_width, int image_height) {

this.image_width = image_width;
this.image_height = image_height;

info[0] = 40;// 用四个字节存储文件的大小

// 位图宽度的保存
int value = image_width;
info[4] = (byte) value;
value = value >> 8;
info[5] = (byte) value;
value = value >> 8;
info[6] = (byte) value;
value = value >> 8;
info[7] = (byte) value;
value = value >> 8;

// 位图高度的保存
value = image_height;
info[8] = (byte) value;
value = value >> 8;
info[9] = (byte) value;
value = value >> 8;
info[10] = (byte) value;
value = value >> 8;
info[11] = (byte) value;

value = Planes;
info[12] = (byte) value;

info[14] = (byte) biBitCount;
3、图片存储数组:
// 一个像素有三个字节组成

// 但是image_size是int型,由4个字节组成,因此image_size必须是
image_size = image_width * image_height * 3;

/*
* 如果位图的宽度不能被3整除,则在后面补零 图片实际大小和占用空间大小的区别
*/
if (image_width % 4 != 0) {
image_size += (image_width % 4) * image_height * 3;
}
4、文件的写入:
public boolean BMPSave(String path,int[][] array) throws IOException{

boolean result=false;
//实例化输出流对象
FileOutputStream fos=new FileOutputStream(path);
//创建文件缓冲流
        BufferedOutputStream bos=new BufferedOutputStream(fos);
        //创建文件数据类型输入流
        DataOutputStream dos=new DataOutputStream(bos);
        //读入文件宽
        dos.writeInt(array[0].length);
        dos.writeInt(array.length);
      //循环写入每个像素点颜色值
for(int i=0;i<array.length;i++){
for(int j=0;j<array[0].length;j++){
dos.writeInt(array[i][j]);
}
}
result=true;
dos.flush();
dos.close();
bos.close();
fos.close();
return result;
}
5、文件的保存:
public void SaveBMP(String path,BufferedImage  bufferedIma) throws IOException{

//输出流对象
OutputStream os=new FileOutputStream(path);
//得到图片的宽和高
int image_width=bufferedIma.getWidth();
int image_height=bufferedIma.getHeight();
//保存图片的大小,图片的大小,即图片的像素
int image_size=image_width*image_height*3;
if(image_width%4!=0){
//补0
image_size+=(image_width%4)*image_height*3;
    }
//定义存取RGB值的数组
byte[] RGBs=new byte[3];
//补0个数的数组
byte[] blank=new byte[image_width%4];
FileHead_BMP fileHead=new FileHead_BMP(image_size,54);//54是文件的偏移量
//1、写入文件头基本信息:文件的大小和偏移量
os.write(fileHead.fileHeadData());
//2、实例化文件位图信息头
InfoHead_BMP infoHead=new InfoHead_BMP(image_width,image_height);
//写入文件位图信息头信息:图片的宽、高和大小
os.write(infoHead.getData());
System.out.println();
/*
* 写入颜色表
*/
//像素计数器
int PixelsValue=0;
for(int y=image_height-1;y>=0;y--){
for(int x=0;x<image_width;x++){
PixelsValue+=3;
int RGB=bufferedIma.getRGB(x, y);
//将像素值转换成字节,存取到RGBs数组中
RGBs[0]=(byte)RGB;
RGB=RGB>>8;
RGBs[1]=(byte)RGB;
RGB=RGB>>8;
    RGBs[2]=(byte)RGB;
    //写入RGBs数据
    os.write(RGBs);
    //如果像素大小不是3的倍数,则将补的0写进去
    if(((image_width%4)!=0)&&(PixelsValue%(image_width*3)==0)){
    os.write(blank);
    }
}
}
os.close();
}
6、文件的读取:
/BMP文件打开操作

public void BMPOpen(String path,int[][] array,DrawingPanel dp) throws IOException{
//创建文件输入流
        FileInputStream fis=new FileInputStream(path);
        //创建文件缓冲流
        BufferedInputStream bis=new BufferedInputStream(fis);
        //创建文件数据类型输入流
        DataInputStream dis=new DataInputStream(bis);
        int width=dis.readInt();
        int height=dis.readInt();
        for(int i=0;i<array.length;i++){
        for(int j=0;j<array[i].length;j++){
        array[i][j]=dis.readInt();
        }
        }
        //关闭流
        //dis.flush();
dis.close();
bis.close();
fis.close();
dp.repaint();
}
7、文件的打开:

public int[][] OpenBMP(String path) throws IOException{

//创建文件输入流
        FileInputStream fis=new FileInputStream(path);
        //创建文件缓冲流
        BufferedInputStream bis=new BufferedInputStream(fis);
        //创建文件数据类型输入流
        DataInputStream dis=new DataInputStream(bis);
        //读入BMP文件头信息
int bflen=14;
byte bf[]=new byte[bflen];
dis.read(bf,0,bflen);
//读入位图信息头
byte[] bi=new byte[40];
dis.read(bi,0,40);
//获取一些重要信息,图形的长与宽
int image_width=changeInt(bi,7);//宽
int image_height=changeInt(bi,11);//高
//位数
int nbitCount=((int)bi[14]&0xff)<<8|(int)bi[14]&0xff;
//源图大小
int nSizeImage=changeInt(bi,23);
int skip_width=0;


DrawingPanel.value_color=new int[image_height][image_width];
/*
*判断是否补0
*/
if(image_width*3%4!=0){
skip_width=4-image_width*3%4;//补0
}
//装载RGB颜色数据数组
imageR =new int[image_height][image_width];
imageG=new int[image_height][image_width];
imageB=new int[image_height][image_width];
for(int h=image_height-1;h>0;h--){
System.out.println("image_width>>>"+image_width+"      " +
" image_height>>>"+image_height);

for(int w=0;w<image_width;w++){
//分别读入B,G,R,倒着读
int blue=dis.read();
int green=dis.read();
int red=dis.read();
System.out.println("blu="+blue+"green="+green+"red="+red);
imageR[h][w]=red;
imageG[h][w]=green;
imageB[h][w]=blue;

if(w==image_width-1){
//跳过补0项
System.out.println(dis.skipBytes(skip_width));
}
Color color=new Color(red,green,blue);
DrawingPanel.value_color[h][w]=color.getRGB();
}
}
//清空数据流
dis.close();
bis.close();
fis.close();
return DrawingPanel.value_color;
}
8、其中还需要字节和整形的转换:
a、字节转换成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));
}
b、int型转换成byte
public byte[] changeByte(int num){

byte b1=(byte)(num>>24);
byte b2=(byte)(num>>16);
byte b3=(byte)(num>>8);
byte b4=(byte)(num);
byte[] by={b4,b3,b2,b1};
return by;
}
分享到:
评论

相关推荐

    java 面试题 总结

    JAVA相关基础知识 1、面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用...

    j2me 游戏开发实例_华容道

    美工这里我找了个捷径,盗用网上现成的图片,然后用ACDSee把它由BMP转换成PNG格式(我出于讲座的目的,未做商业应用,应该不算侵权吧);至于发布工作,由于缺少OTA服务器,此项工作不做(但是我会介绍这步如何做)。 ...

    VC PICTURE控件的使用

    VC PICTURE控件的使用,如何加载背景图片2009年04月19日 星期日 15:02vc picture控件的分类总结: (一) 非动态显示图片(即图片先通过资源管理器载入,有一个固定ID) (二) 动态载入图片(即只需要在程序中指定图片的...

    网管教程 从入门到精通软件篇.txt

    小编的确一直都想把这方面的命令做个总结,这次辛苦老范给我们整理了这份实用的秘笈。  Bootcfg  bootcfg 命令启动配置和故障恢复(对于大多数计算机,即 boot.ini 文件)。  含有下列参数的 bootcfg 命令仅在...

    vc++ 开发实例源码包

    很简单,只能播放mp3格式的音乐。 功能: --------------------------------------- --------关闭-- 打开----最小化------- --------------------------------------- 显示歌曲名字 -------------------- -------...

    网页设计毕业实习报告.docx

    要注意,网上只能使用JPG和GIF两种图象格式,其他诸如BMP和TIF等很通用的格式都不能用在网上,因为它们太大了,但可以用图象软件进行转换,比如Office 97的照片编辑器。把准备在主页上出现的图象放进相应的目录里后. 在...

    PS设计课程作业剖析.docx

    下面介绍 Photoshop 的基本功能: 1、 图像格式:Photoshop 支持多种高质量的图像格式,包括 PSD、TIF、JPG、BMP、EPS、 PCX、FLM、PDF、RAW 和 SCT 等 20 多种。 图像尺寸和分辨率:可以按要求任意调整图像的尺寸...

    vc++ 应用源码包_1

    实例简单,有用户登录、传输文件、视频、画质调节、禁音检测、回音消除、自动增益、噪音抑制、视频控制等、 VC++搜索指定文件夹中的文件 VC++文件分割、合并工具 自绘了Button、CProgressCtrl、CAutoFont。主要...

    vc++ 应用源码包_2

    实例简单,有用户登录、传输文件、视频、画质调节、禁音检测、回音消除、自动增益、噪音抑制、视频控制等、 VC++搜索指定文件夹中的文件 VC++文件分割、合并工具 自绘了Button、CProgressCtrl、CAutoFont。主要...

    vc++ 应用源码包_6

    实例简单,有用户登录、传输文件、视频、画质调节、禁音检测、回音消除、自动增益、噪音抑制、视频控制等、 VC++搜索指定文件夹中的文件 VC++文件分割、合并工具 自绘了Button、CProgressCtrl、CAutoFont。主要...

    vc++ 应用源码包_5

    实例简单,有用户登录、传输文件、视频、画质调节、禁音检测、回音消除、自动增益、噪音抑制、视频控制等、 VC++搜索指定文件夹中的文件 VC++文件分割、合并工具 自绘了Button、CProgressCtrl、CAutoFont。主要...

    vc++ 应用源码包_3

    实例简单,有用户登录、传输文件、视频、画质调节、禁音检测、回音消除、自动增益、噪音抑制、视频控制等、 VC++搜索指定文件夹中的文件 VC++文件分割、合并工具 自绘了Button、CProgressCtrl、CAutoFont。主要...

Global site tag (gtag.js) - Google Analytics