JAVA学习网首页 把生活查询网加入收藏 把JAVA学习网设为首页 联系方式
    Hi,JAVA学习
JAVA基础 设计模式 数据库 JavaBeans J2EE JavaDelphi 用户界面 综合文章  
如何将BufferedImage实例保存为BMP文件
时间:02/10/2007
作者:未知
来源:网络
小提示点这里把文章加入您的收藏夹,方便下次查看
设置文章字体大小:[ ]
 要将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 %
上一篇:如何把一图画变成图形界面的背景

下一篇:格式化消息(参数替换)

  • 通过实例了解接口的含义
  • 数组排序1例
  • abstract class && Interface 比较
  • 在Tomcat里发布程序
  • JB的调试方法(欢迎补充)
  • Java学习从入门到精通
  • JAVA实现调用本地命令
  • org.eclipse.ui.console指南
  • BeanShell快速入门---Java应用程序脚本引擎
  • Java中文问题及最优解决方法
  • 异常的异常 - 理解真正的开销
  • EnterpriseJavaBeansDistilled(8)
  • Swing 编程 LayoutManager 的应用
  • java tips
  • JSP 自定义标记符库
  • Interface与Abstract class的异同
  • J2SE 5.0实例---原生类型的autoboxing和auto-unboxing
  • 一个聊天室中遇到的问题!
  • 返回】 【顶部】 【关闭
    Copyright © 2005-2010 www.594k.com All Rights Reserved.
    版权所有:JAVA学习网 备案序号:皖ICP备06004238号