`
李瑞辉++
  • 浏览: 20676 次
  • 性别: Icon_minigender_1
  • 来自: 信阳
社区版块
存档分类
最新评论

BMP

 
阅读更多

         

一、    介绍

   开始之前先讲一下原始数据读写流DataOutputStreamDataInputStream

主要用来读写指定的数据类型的数据。两种数据流都以对应的文件输入

输出流为构造参数:

下面是几个数据输出流的几个方法(来至API):

writeBoolean(boolean v)

              将一个 boolean 值以 1-byte 值形式写入基础输出流。

writeByte(int v)
                    
将一个 byte 值以 1-byte 值形式写出到基础输出流中

writeChar(int v)
                    
将一个 char 值以 2-byte 值形式写入基础输出流中,先写入高字节。

writeLong(long v)
                     
将一个 long 值以 8-byte 值形式写入基础输出流中,先写入高字节。

以上都在数据输出流里有对应的方法,而且我们在读取数据时必须循序读取,而且类型要匹配,文件在存储数据时,是以byte形式储存的,例如,一个int 类型的数据,储存时会被拆成四个字节然后按高位到低位进行储存,所以在读取数据时必须匹配,不然会有数据丢失,储存时也是如此。

二、解析BMP文件格式:

任何文件在储存时都有自己的文件格式,而且这并不取决于扩展名,例如BMP文件,在储存时不仅包含画板上获取的数据,在储存是要提前写入一些文件头信息。

BMP文件有四部分组成:

1、        位图文件头数据结构,它包含BMP图像文件的类型、显示内容等信息;

2、         位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及自定义颜色等信息;

3、        调色板:这个部分是可选的,有些位图需要调色板,有些位 图,比如我做的24位真彩图就不需要调色板

4、       位图数据:这部分根据BMP位图使用的位数不同而不同,在24位图中直接使用RGB,而其他的小于24位的使用调色板中颜色索引值。

三、    实现

实现主要分为两个部分,写入和读取,必须得按照BMP本身格式类型进行操作

写入:

/**

     * 

     * @param image:截取的图片

     * @param file:要存储的文件

     */

    public void saveBMP(BufferedImage image,File file) {

       try {

           /* 创建文件输出流 */

           java.io.FileOutputStream fos = new FileOutputStream(file);

           /* 文件数据输出流 */

           java.io.DataOutputStream dos = new DataOutputStream(fos);

 

           //////////////////////////////////////////////*BMP文件头*/

           int width = image.getWidth();

           int height = image.getHeight();

           /* 位图文件类型,2个字节 */

           dos.writeByte((int) 'B');

           dos.writeByte((int) 'M');

           /* 位图文件大小,4个字节 */

           int skip_width = 0;

/* Windows规定一个扫描行所占的字节数必须为4的倍数,不足的以0补上*/

           if (width * 3 % 4 != 0)

              skip_width = 4 - width * 3 % 4;

           int bfsize = 54 + (width + skip_width) * 3 * height;

           dos.write(changeIntTobyte(bfsize, 4), 0, 4);

           /* 文件的两个保留字,4个 */

           dos.write(changeIntTobyte(0, 4), 0, 4);

 

           /* 起始位置4个字节 */

           dos.write(54);

           dos.write(changeIntTobyte(0, 3), 0, 3);

 

           // ////////////////////////////////////////////*位图信息图*/

           /* 本结构所占字节数40,4个字节 */

           int size = 40;

           dos.write(changeIntTobyte(size, 4), 0, 4);

           /* 宽度,高度,8个字节 */

           dos.write(changeIntTobyte(width, 4), 0, 4);

           dos.write(changeIntTobyte(height, 4), 0, 4);

           /* 目标设备 */

           dos.write(changeIntTobyte(1, 2), 0, 2);

           /* 像素所需位数 24*/

           dos.write(changeIntTobyte(24, 2), 0, 2);

           /* 压缩类型 */

           dos.write(changeIntTobyte(0, 4), 0, 4);

           /* 位图大小 */

           dos.write(changeIntTobyte(0, 4), 0, 4);

           /* 水平,垂直分辨率 */

           dos.write(changeIntTobyte(150, 4), 0, 4);

           dos.write(changeIntTobyte(150, 4), 0, 4);

           /* 位图实际使用的颜色表,的颜色数 */

           int numcolor = 0;

           dos.write(changeIntTobyte(numcolor, 4), 0, 4);

           /* 重要的颜色 */

           int impcolor = 0;

           dos.write(changeIntTobyte(impcolor, 4), 0, 4);

 

           // ///////////////////////////////////////////位图数据

           int color[][] = new int[height][width];

           byte imageR[][] = new byte[height][width];

           byte imageG[][] = new byte[height][width];

           byte imageB[][] = new byte[height][width];

 

           for (int h = 0; h < height; h++) {

              for (int w = 0; w < width; w++) {

 

                  int temp = image.getRGB(w, h);

                  color[h][w]  = temp;

                  imageR[h][w] = (byte)( temp >> 16);

                  imageG[h][w] = (byte)( temp >> 8);

                  imageB[h][w] = (byte)( temp >> 0);

              }

 

           }

           

           for(int h= height - 1;h>-1;h--)

              for(int w =0 ;w<width;w++){

              dos.writeByte(imageB[h][w]);

              dos.writeByte(imageG[h][w]);

              dos.writeByte(imageR[h][w]);

                  

                  if(skip_width!=0&&w == 0){

                   

                         dos.write(changeIntTobyte(0,skip_width),0,skip_width);

                  }         

           }

                  fos.flush();

                  fos.close();

           

       } catch (IOException exception) {

           exception.printStackTrace();

       }

 

    } 

 

 

 

 

 

 

 

 

 

 

 

 

   

以上还有一点比较重要,前面我们已经知道文件存储数据是以byte形式,从高位到低位存储的,但对于位图文件有点特殊,它是从低位到高位存储的,所以我在存储时要手动把数据转成byte型并以从低位到高位存入文件中,系统将会读取错误

 

 public byte[] changeIntTobyte(int num, int size) {

       byte[] count = new byte[size];

 

       for (int i = 0; i < size; i++) {

           count[i] = (byte) (num >> (i * 8));

       }

 

       return count;

}


 

   对于读取只是按照以上步骤读取即可,记住一点,要把读入的数据再按位组合成所需要的数据,即使以上转化的逆过程。通过以上的过程就可以把画图板图片保存成BMP文件了,而且可以用windows 的图片查看了。不过只限于24位的欧。

四、    文件选择器的使用

以上已经实现了功能,下面是一点拓展,在实现存储和打开文件时我使用了文件选择器

 

public void saveFile() {

           

           try{

 

           FileFilter filter1 = new FileFilter() {

               

              public boolean accept(File file) {// 只显示  bmp 格式的文件或文件夹

                  String formatName = file.getName().toLowerCase();

                  return formatName.endsWith(".bmp") || file.isDirectory();

              }

 

              @Override

              public String getDescription() {// 文件描述为 bmp

                  // TODO Auto-generated method stub

                  return "bmp";

              }

 

           };

           

           JFileChooser jfc = new JFileChooser();// 文件选择器

           jfc.setAcceptAllFileFilterUsed(false);// 不显示所有文件

           jfc.setName("保存");// 标题

           jfc.addChoosableFileFilter(filter1);// 加上过滤器

 

           jfc.setCurrentDirectory(new File("src\\MyBMP\\images"));// 文件选择器的初始目录

           File outfile;//用来获得文件

           int state = jfc.showSaveDialog(drawPanel);// 此句是打开文件选择器界面的触发语句

           if (state == 1) {

 

              return;// 撤销则返回

           } else {

              outfile = jfc.getSelectedFile();// f为选择到的文件名

 

           }

           /* 判断是否以bmp为后缀名,不管大小 */

           String formatName = "bmp";// 指定为bmp

           String filename = outfile.getAbsolutePath().toLowerCase();// 获得路径

           if (!filename.endsWith(formatName))// 如果输入时未加上后缀则自动加上后缀

               outfile = new File(filename + "." + formatName);

           //自定义函数

           saveBMP(image, outfile);

           //系统函数,

           //javax.imageio.ImageIO.write(image, formatName, outfile);

 

       } catch (java.awt.AWTException exception) {

 

           exception.printStackTrace();

 

       }

       

}

 

加上文件选择器就可以动态写文件名了,省的一直对一个文件进行操作,也变得更人性化了,这就是我的真正BMP。。。敬请指正。。

分享到:
评论

相关推荐

    BMP280.rar_bmp280测海拔_bmp280测高度_bmp280海拔_bmp280读取气压_气压计bmp280

    BMP280是一款高度集成的数字压力和温度传感器,由德国博世(Bosch)公司生产。这个压缩包文件"BMP280.rar"包含了有关如何使用BMP280传感器进行海拔、高度和气压测量的相关资源,以及可能的驱动程序和用户移植接口,...

    bmp 经典小图标bmp 经典小图标

    BMP(Bitmap)是一种常见的位图图像格式,广泛用于操作系统、应用程序和游戏中的图标资源。它以未经压缩的原始像素数据存储图像,支持多种颜色深度,包括灰度、24位真彩色等。在编程中,BMP文件常被用作程序的图标,...

    32位bmp转24位bmp

    在图像处理领域,BMP(Bitmap)是一种常见的位图文件格式,用于存储未经过压缩的图像数据。32位和24位BMP文件的区别主要在于颜色深度和透明度支持。32位BMP文件每像素包含4个字节,分别代表红、绿、蓝(RGB)三个颜色...

    51读气压计_气压计读取BMP085_51单片机读取BMP280_

    在本主题中,我们将专注于如何使用51单片机读取BMP085和BMP280这两种气压计的数据,以及如何通过这些数据计算海拔高度和进行内部温度补偿。 首先,BMP085和BMP280都是博世(Bosch)公司生产的高度集成的气压和温度...

    24位BMP转32位BMP

    在图像处理领域,BMP(Bitmap)是一种常见的位图文件格式,用于存储图像数据。24位BMP和32位BMP的区别在于它们的颜色深度,即每像素所占用的位数。24位BMP提供了8位红、8位绿、8位蓝三种颜色通道,总共能表示...

    bmp文件读出为txt文件, txt文件写入为bmp文件

    在IT领域,BMP(Bitmap)是一种常见的位图图像文件格式,广泛用于存储数字图像。本文将详细讨论如何从BMP文件读取数据并将其转换为TXT文本文件,以及如何将TXT文件的数据重新写入为BMP文件。这两个过程涉及到二进制...

    24为bmp转8位bmp

    24位BMP图像转为8位BMP图像的处理涉及到图像像素深度的转换。24位BMP图像(也称为真彩色图像)每个像素用24位(即3个字节)来表示颜色,每个颜色通道(红色、绿色、蓝色)占8位。相比之下,8位BMP图像使用8位来表示...

    vb6直接读取bmp图片显示的源码 vb6分析bmp图片 vb6处理bmp图片

    在VB6(Visual Basic 6)中,读取并显示BMP(Bitmap)图片涉及到图形图像处理的基础知识,包括理解BMP文件格式、内存管理以及控件的使用。以下将详细讲解这些知识点。 首先,BMP是一种无损的位图格式,它存储了图像...

    bmp转十六进制 适用于单片机显示bmp图片

    在电子工程和嵌入式系统领域,BMP(Bitmap)图像是一种常见的图形文件格式,它包含了大量的像素数据,用于在屏幕上显示图像。然而,当我们要在单片机或嵌入式系统上显示图像时,由于资源限制,通常需要将这些复杂的...

    图片转换工具(jpg转8位bmp,24位bmp转8位bmp)

    本工具专注于将图片从一种格式转换为另一种,特别是JPEG(jpg)与不同位深度的Bitmap(bmp)之间的转换。以下是关于这个主题的详细知识: 1. **JPEG与Bitmap格式**: JPEG(Joint Photographic Experts Group)是...

    BMP图片转RGB数组

    在计算机图形学中,BMP(Bitmap)是一种常见的位图图像格式,用于存储像素数据。在Windows操作系统中,BMP文件被广泛使用。RGB(Red, Green, Blue)是颜色模型的一种,它通过红、绿、蓝三种颜色的组合来表示几乎所有...

    linux下bmp图像显示

    在Linux系统中,显示BMP图像涉及到对位图文件格式的理解以及使用framebuffer设备驱动进行图形输出。BMP(Bitmap)是一种常见的未经压缩的图像文件格式,它存储了像素颜色值,而framebuffer则是Linux内核提供的一种...

    RGB565直接转BMP

    与之相比,BMP(Bitmap)文件格式是微软开发的一种位图图形文件格式,广泛应用于Windows和一些其他操作系统中。BMP文件包含了图像的所有像素数据,包括颜色深度、宽度、高度、图像数据等信息,因此它通常比其他压缩...

    BMP180_API

    BMP180_API 是一个与BMP180气压传感器相关的软件开发包,它包含了必要的函数和头文件,使得开发者能够轻松地在他们的项目中集成这个传感器。BMP180是由德国博世(Bosch)公司生产的一款高度精确、低功耗的数字气压和...

    bmp2c 源码+工具bmp转c数组

    标题提到的"bmp2c 源码+工具bmp转c数组"就是一个这样的工具,它能够将BMP图像文件转换为C语言的二维字符数组,方便在嵌入式程序中使用。 BMP(Bitmap)是微软公司定义的一种位图格式,广泛用于Windows和OS/2操作...

    将BMP文件数据转换为TXT文件.zip

    BMP文件是一种位图图像格式,广泛用于存储各种图像。它以未经压缩的原始像素数据存储,这使得BMP文件在处理图像数据时非常直观,但同时也导致文件尺寸相对较大。这个压缩包“将BMP文件数据转换为TXT文件.zip”包含了...

    C# JPG转换BMP文件

    bmpImage.Save("path_to_save_bmp_file.bmp", ImageFormat.Bmp); ``` 以上代码实现了JPG到BMP的转换。需要注意的是,由于BMP格式不支持压缩,转换后的文件体积会比原始JPG文件大很多。如果对文件大小有顾虑,可以...

    bmp180_api.gz_BMP180_bmp180_api_bmp180api使用

    在嵌入式系统中,为了与BMP180进行通信并获取数据,开发人员通常会使用特定的API库,比如在给定的"bmp180_api.gz"压缩包中包含的"BMP180_bmp180_api_bmp180api"。 这个API库主要由两个文件组成:`bmp180.c`和`bmp...

    BMP_bmp解压_bmp压缩_bmp怎么解压缩_bmp文件解压_bmp文件压缩解压_

    标题和描述提到的“BMP_bmp解压_bmp压缩_bmp怎么解压缩_bmp文件解压_bmp文件压缩解压”都是围绕BMP文件的压缩和解压缩操作展开的。接下来,我们将深入探讨BMP文件的结构、压缩原理以及如何进行压缩与解压缩。 首先...

    BMP388代码和资料.zip

    【BMP388代码和资料.zip】是一个包含有关BMP388气压传感器及其在STM32微控制器上应用的资源包。这个压缩文件提供了必要的文档、原理图和代码,帮助开发者理解和使用BMP388传感器,并将其集成到STM32系统中。 **BMP...

Global site tag (gtag.js) - Google Analytics