BMP总结

                    BMP总结

    对于我来说画图板的BMP格式的打开与保存这一项目做得还是比较艰难,听冠毅同学简单的向我们介绍了一下BMP,有格式的转换和它的语法规则等,但也仅仅是有了初步的了解,当时觉得用BMP做画图板的保存与打开还是一头雾水。所以我先另外创建了一个类单做打开与保存这一部分,再加到画图板上,在左哥的帮助下有了大概的思路:

打开:

创建文件输入流——>读入BMP文件头:

byte[] bf = new byte[14];

           dos.read(bf);

——>读取位图信息头:

byte[] bi = new byte[40];

           dos.read(bi);

            //调用ChangeInt方法,得到图形的长与宽,是倒着调用的,7为下面int x4=(int)bi[start-3]&0xff;中的,

           chang=ChangeInt(bi,7);

          

           //后三个为宽度

           kuan=ChangeInt(bi,11);

           int biSizeImage =ChangeInt(bi,23);

——>将读取到的信息存到监听器中创建的area数组中:

           DrawListener.area=new int[kuan][chang];

——>读取图像像素:

//一个像素占三个字节,windows规定扫描行所占的字节数,必须是4的倍数

           //如果不是4的倍数就要补零

            if((chang*3%4)!=0){

               skip_chang = 4-chang*3%4;

           }

            //装载RGB颜色数据数组

           imageR = new int[kuan][chang];

           imageG=new int[kuan][chang];

           imageB=new int[kuan][chang];

            

        //按行读取——从左到右,从下到上

            for(int i=kuan-1;i>=0;i--){

               for(int j=0;j<chang;j++){

                  //读取三原色

                  int blue=dos.read();

                  int green=dos.read();

                  int red=dos.read();

                  System.out.println("blu="+blue+"green="+green+"red="+red);

                  //将读取出来的颜色放入RGB数组中

                  //倒着读

                  imageB[i][j]=blue;

                  imageG[i][j]=green;

                  imageR[i][j]=red;

                  if(j==0){

                  //跳过补0的项

                  dos.skipBytes(skip_chang);

                  }

——>将撒按原色转为颜色:

    Color color=new Color(red,green,blue);

                  //将相对应的颜色转为整形存入数组中

                  DrawListener.area[i][j]=color.getRGB();

——>最后调用repaint方法,将此方法加到界面的按钮监听器上:else

           if (command.equals("open")) {

 

           int t = chooser.showOpenDialog(null);

           if (t == 0) {

              String path = chooser.getSelectedFile().getAbsolutePath();

          

          

              // 读取文件,得到队列,作为画板要使用的队列

              openShapes(path);

//            openShapes(dos,chang,kuan);

              System.out.println("path"+path);

              jp.repaint();

           }

实现对BMP格式图像的打开。

保存:

再来说说保存吧,其实搞清楚了BMP格式文件的结构,保存便很简单,在一个方法中写入文件的各个结构大体思路为:

先得到画布的宽度与长度:

//得到画布的宽度与高度

        int chang=jp.getWidth();

        int kuan=jp.getHeight();

——>创建一个文件输出流对象:java.io.FileOutputStream output=new java.io.FileOutputStream(path);

           java.io.DataOutputStream output1=new java.io.DataOutputStream(output);

——>写入图片的头文件:

/**//**

   *  Title: BMP文件的头结构

   *

   *  Description: BMP文件的头结构固定是14个字节,其定义如下:

   *

   * byte[2] bfType; 指定文件类型,必须是0x424D,即字符串“BM”,也就是说所有.bmp文件的头两个字节都是“BM“

   * byte[4] bfSize; 指定文件大小,包括这14个字节

   * byte[2] bfReserved1; 保留字

   * byte[2] bfReserved2; 保留字

   * byte[4] bfOffBits; 为从文件头到实际的位图数据的偏移字节数

   */

//位图文件类型(BMString,所以将字符串转为字节)

           byte[] bt=new byte[2];

           bt[0]='B';

           bt[1]='M';

           output1.write(bt,0,2);

 

   //文件大小(加上跳过的字节)

           int bSize=54+chang*kuan*3;

           output1.write(ChangByte(bSize),0,4);

           //文件保留字

           int Reserved1=0;

           output1.write(ChangByte(Reserved1),0,2);

           int Reserved2=0;

           output1.write(ChangByte(Reserved2),0,2);

           //偏移量

           int bOffbits=54;

           output1.write(ChangByte(bOffbits),0,4);

——>写入文件信息头:

/**//**

   * Title: BMP文件内容的头结构

   *

   * Description: BMP文件内容的头结构固定是40个字节,其定义如下:

   *

   * byte[4] biSize; 指定这个结构的长度,为40

   * byte[4] biWidth; 指定图象的宽度,单位是象素

   * byte[4] biHeight; 指定图象的高度,单位是象素

   * byte[2] biPlanes; 必须是1,不用考虑

   * byte[2] biBitCount; 指定表示颜色时要用到的位数,常用的值为1(黑白二色图), 4(16色图), 8(256), 24(真彩色图)

   * byte[4] biCompression; 指定位图是否压缩

   * byte[4] biSizeImage; 指定实际的位图数据占用的字节数

   * byte[4] biXPelsPerMeter; 指定目标设备的水平分辨率,单位是每米的象素个数

   * byte[4] biYPelsPerMeter; 指定目标设备的垂直分辨率,单位是每米的象素个数

   * byte[4] biClrUsed; 指定本图象实际用到的颜色数,如果该值为零,则用到的颜色数为2biBitCount

   * byte[4] biClrImportant; 指定本图象中重要的颜色数,如果该值为零,则认为所有的颜色都是重要的

   *

   */

//本结构所占用的字节数

           int Size=40;

           output1.write(ChangByte(Size),0,4);

           //位图宽度

           int chang1=chang;

           output1.write(ChangByte(chang1),0,4);

           int kuan1=kuan;

           output1.write(ChangByte(kuan1),0,4);

           //plane总数

           int plane=1;

           output1.write(ChangByte(plane),0,2);

           //记录颜色的位数

           int Countbit=24;

           output1.write(ChangByte(Countbit),0,2);

           //数据压缩方式(不压缩)

           int Compression=0;

           output1.write(ChangByte(Compression),0,4);

           //图像区数据的大小

           int SizeImage=chang*kuan;

           output1.write(ChangByte(SizeImage),0,4);

           //水平每米有多少像素

           int XPelsPerMeter=0;

           output1.write(ChangByte(XPelsPerMeter),0,4);

           //垂直每米有多少像素

           int YPelsPerMeter=0;

           output1.write(ChangByte(YPelsPerMeter),0,4);

           //所用颜色数

           int ClrUsed=0;

           output1.write(ChangByte(ClrUsed),0,4);

           //重要颜色数

           int ClrImportant=0;

           output1.write(ChangByte(ClrImportant),0,4);

——>因为24位的不需要调色区所以我们不需要写入

——>写入图像数据区:

for(int i=kuan-1;i>=0;i--){

              for(int j=0;j<chang;j++){

                 int Cnum=DrawListener.area[i][j];

                 Color color=new Color(Cnum);

                 //将颜色RGB输出

                 output1.write(ChangByte(color.getBlue()),0,1);

                 output1.write(ChangByte(color.getGreen()),0,1);

                 output1.write(ChangByte(color.getRed()),0,1);

                

              }

           }

——>最后将这一方法加到界面的按钮监听器按钮上:

if (command.equals("save")) {

 

           int t = chooser.showSaveDialog(null);

           if (t == 0) {// 如果点击的是保存

 

              String path = chooser.getSelectedFile().getAbsolutePath();

              // 保存文件

          

           save(path);

           System.out.println("path"+path);

           }

实现以BMP格式的保存。

在整个过程中我遇到的最大的问题首先是打开和保存的方法写了,也没报错但在画图板上操作时没反应,其实这个问题不是出在方法本身而是根本就没调用这个方法,没有实现这个方法,就是在按钮的监听器条件设置是方法没调用对;第二个问题是所要打开的图形和画布大小的设置,我最先的错误思路是先要把huabu这个对象传到我创建的实现打开与保存的这个监听器中,再将读取到的图像的大小赋予画布,让画布的大小和将要打开的图像的大小一样,这样做明显是不正确的,其实这个问题的解决方法也很简单,不用传只要画布的比图片大就行而在保存时只要在JPanel jp对象上得到画布的长和宽就可以了。

其实现在回过头去再看看,它的思路很简单,有时就是自己讲问题看得太复杂了,还没开始做就开始打退堂鼓,所以以后要像东哥和龙哥常说的要敢于做。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值