当前位置导航:炫浪网>>网络学院>>编程开发>>JAVA教程>>Java进阶

如何将BufferedImage实例保存为BMP文件


  要将BufferedImage实例保存为BMP文件,就需要知道BMP文件的格式,可以参考我转载的文章:《BMP文件格式》。
  
  下面是我的将BufferedImage实例保存为24位色BMP文件的实现。
  
  首先是BMP文件相关的两个头结构:BMPFileHeader和BMPInfoHeader。
  
  /**//*
  * Created on 2005-6-21
  *
  * TODO To change the template for this generated file go to
  * Window - Preferences - Java - Code Style - Code Templates
  */
  package org.lotus.image.codec.bmp;
  
  /**//**
  * <p> Title: BMP文件的头结构</p>
  *
  * <p> Description: BMP文件的头结构固定是14个字节,其定义如下:</p>
  * <p>
  * byte[2] bfType;          指定文件类型,必须是0x424D,即字符串“BM”,也就是说所有.bmp文件的头两个字节都是“BM“
  * byte[4] bfSize;          指定文件大小,包括这14个字节
  * byte[2] bfReserved1;      保留字
  * byte[2] bfReserved2;      保留字
  * byte[4] bfOffBits;        为从文件头到实际的位图数据的偏移字节数
  * </p>
  *
  * <p> Copyright: Copyright (c) 2005</p>
  *
  * <p> Company: 21Lotus</p>
  *
  * @author George Hill
  * @version 1.0
  */
  
  class BMPFileHeader {
  
  // Header data
  private byte[] data = new byte[14];
  
  public byte[] getData() {
  return this.data;
  }
  
  // BMP file size
  private int size;
  
  public int getSize() {
  return this.size;
  }
  
  private int offset;
  
  public int getOffset() {
  return this.offset;
  }
  
  BMPFileHeader(int size, int offset) {
  this.size = size;
  this.offset = offset;
  
  data[0] = 'B';
  data[1] = 'M';
  
  int value = size;
  data[2] = (byte) value;
  value = value >>> 8;
  data[3] = (byte) value;
  value = value >>> 8;
  data[4] = (byte) value;
  value = value >>> 8;
  data[5] = (byte) value;
  
  value = offset;
  data[10] = (byte) value;
  value = value >>> 8;
  data[11] = (byte) value;
  value = value >>> 8;
  data[12] = (byte) value;
  value = value >>> 8;
  data[13] = (byte) value;
  }
  
  }
  
  /**//*
  * Created on 2005-6-21
  *
  * TODO To change the template for this generated file go to
  * Window - Preferences - Java - Code Style - Code Templates
  */
  package org.lotus.image.codec.bmp;
  
  /**//**
  * <p>Title: BMP文件内容的头结构</p>
  *
  * <p>Description: BMP文件内容的头结构固定是40个字节,其定义如下:</p>
  * <p>
  * 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;      指定本图象中重要的颜色数,如果该值为零,则认为所有的颜色都是重要的
  * </p>
  *
  * <p>Copyright: Copyright (c) 2005</p>
  *
  * <p>Company: 21Lotus</p>
  *
  * @author George Hill
  * @version 1.0
  */
  
  class BMPInfoHeader {
  
  private byte[] data = new byte[40];
  
  public byte[] getData() {
  return this.data;
  }
  
  private int width;
  
  public int getWidth() {
  return this.width;
  }
  
  private int height;
  
  public int getHeight() {
  return this.height;
  }
  
  public int bitCount;
  
  public int getBitCount() {
  return this.bitCount;
  }
  
  public BMPInfoHeader(int width, int height, int bitCount) {
  this.width = width;
  this.height = height;
  this.bitCount = bitCount;
  
  data[0] = 40;
  
  int value = width;
  data[4] = (byte) value;
  value = value >>> 8;
  data[5] = (byte) value;
  value = value >>> 8;
  data[6] = (byte) value;
  value = value >>> 8;
  data[7] = (byte) value;
  
  value = height;
  data[8] = (byte) value;
  value = value >>> 8;
  data[9] = (byte) value;
  value = value >>> 8;
  data[10] = (byte) value;
  value = value >>> 8;
  data[11] = (byte) value;
  
  data[12] = 1;
  
  data[14] = (byte) bitCount;
  
  value = width * height * 3;
  if (width % 4 != 0)
  value += (width % 4) * height;
  data[20] = (byte) value;
  value = value >>> 8;
  data[21] = (byte) value;
  value = value >>> 8;
  data[22] = (byte) value;
  value = value >>> 8;
  data[23] = (byte) value;
  }
  
  }
  
  仿照com.sun.image.codec.jpeg.JPEGImageEncoder写的接口类BMPEncoder。
  
  /**//*
  * Created on 2005-6-21
  *
  * TODO To change the template for this generated file go to
  * Window - Preferences - Java - Code Style - Code Templates
  */
  package org.lotus.image.codec.bmp;
  
  import java.awt.image.*;
  import java.io.IOException;
  
  /**//**
  * <p>Title: </p>
  *
  * <p>Description: </p>
  *
  * <p>Copyright: Copyright (c) 2005</p>
  *
  * <p>Company: 21Lotus</p>
  *
  * @author George Hill
  * @version 1.0
  */
  
  public interface BMPEncoder {
  
  public void encode(BufferedImage bi) throws IOException;
  
  public static final int BIT_COUNT_BLACKWHITE = 1;
  public static final int BIT_COUNT_16COLORS = 4;
  public static final int BIT_COUNT_256COLORS = 8;
  public static final int BIT_COUNT_TRUECOLORS = 24;
  
  }
  
  BMPEncoder接口的实现BMPEncoderImpl。
  
  /**//*
  * Created on 2005-6-21
  *
  * TODO To change the template for this generated file go to
  * Window - Preferences - Java - Code Style - Code Templates
  */
  package org.lotus.image.codec.bmp;
  
  import java.awt.image.*;
  import java.io.*;
  
  /**//**
  * <p>Title: </p>
  *
  * <p>Description: </p>
  *
  * <p>Copyright: Copyright (c) 2005</p>
  *
  * <p>Company: 21Lotus</p>
  *
  * @author George Hill
  * @version 1.0
  */
  
  class BMPEncoderImpl implements BMPEncoder {
  
  private OutputStream out;
  
  public BMPEncoderImpl(OutputStream out) {
  this.out = out;
  }
  
  public void encode(BufferedImage bi) throws IOException {
  int width = bi.getWidth();
  int height = bi.getHeight();
  
  boolean needBlank = (width % 4 != 0);
  
  int size = width * height * 3;
  if (needBlank) {
  size += (width % 4) * height;
  }
  
  BMPFileHeader fileHeader = new BMPFileHeader(size, 54);
  BMPInfoHeader infoHeader = new BMPInfoHeader(width, height, BIT_COUNT_TRUECOLORS);
  
  byte[] rgbs = new byte[3];
  byte[] blank = new byte[width %
相关内容
赞助商链接