posts - 28,  comments - 15,  trackbacks - 0

关于bmp文件内部存储格式参看:http://www.yymcu.com/resource/BMP%CE%C4%BC%FE%B8%F1%CA%BD%B7%D6%CE%F6.htm
以下是转换的具体java实现,已经通过单元测试,copy之后能直接使用:
public class TransactionBmpTo16Bit{
 private String resFilePath;
 private String desFilePath;
 private Bmp currentBmp = null;
 
 public TransactionBmpTo16Bit(String resFilePath,String desFilePath){
  this.resFilePath = resFilePath;
  this.desFilePath = desFilePath;
 }
 
 /**
  * 把24bit的bmp图像转换为16bit的图像
  *
  * @return
  */
 public boolean transacte(){
  currentBmp = new Bmp();
  try {
   byte[] fileContent = currentBmp.loadBmp(resFilePath);
   Bmp desBmp = new Bmp();
   byte[] changeContent = this.changeContent(fileContent);
   desBmp.setCurrent(changeContent);
   desBmp.save(desFilePath);
  } catch (IOException e) {
   e.printStackTrace();
   return false;
  } catch (BusinessException e) {
   e.printStackTrace();
   return false;
  }
  return true;
 }
 
 /**
  * 获得新文件的大小
  *
  * @return
  */
 private int getNewFileSize(){
  return  currentBmp.getWeight()*currentBmp.getHight()*2+currentBmp.getDataOffset();
 }
 
 private byte[] changeContent(byte[] current){
  
  int newSize = this.getNewFileSize();
  byte[] newByt = new byte[newSize];
  for(int i=0;i<currentBmp.getDataOffset();i++){
   newByt[i] = current[i];
  }
  /*设置新的位图大小*/
  byte[] sbt = NumberConversion.intToBytes(newSize,4);
  for(int i=2;i<6;i++){
   newByt[i]=sbt[5-i];
  }
  /*设置新的像素位数*/
  byte[] pixDigit = NumberConversion.intToBytes(16,2);
  newByt[28] = pixDigit[1];
  newByt[29] = pixDigit[0];
  
  
  //TODO 获得转化后的数据实现
  int dataSize = newSize-54;
  
  byte[] newData = new byte[dataSize];
  
  byte[][] data = this.getFiltratedArray(current);
  int tt = 0;
  for(int i=0;i<currentBmp.getHight();i++){
   
   for(int j=0;j<currentBmp.getWeight()*3;j++){
    tt+=1;
    if((j+1)%3==0){
     byte n = (byte) ((((data[i][j-1])>>>5)&0x7)|(data[i][j]&0xF8));
     byte m = (byte) (((data[i][j-2]>>>3)&0x1F)|((data[i][j-1]&0x1c)<<3));
     int index = tt/3*2;
     newData[index-2] = m;
     newData[index-1] = n;
    }
   }
  }
  for(int i=54;i<newSize;i++){
   newByt[i] = newData[i-54];
  }
  return newByt;
 }
 
 /**
  * 过滤bmp补位的数据
  * @return
  */
 private byte[][] getFiltratedArray(byte[] current){
  
  int residue = (this.currentBmp.getWeight()*3)%4;
  int skip = 0;
  if(residue!=0) skip = 4-residue;
  
  byte[][] array = new byte[this.currentBmp.getHight()][this.currentBmp.getWeight()*3];
  
  int scale = this.currentBmp.getDataOffset();
  
  for(int i=0;i<this.currentBmp.getHight();i++){
//   scale += i*hight;
   for(int j=0;j<this.currentBmp.getWeight()*3;j++){
    
    array[i][j] = current[scale];
    scale += 1;
   }
//   System.out.println("scale="+scale);
   scale+=skip;
//   System.out.println("scale1="+scale);
  }

  return array;
  
 }
 
}

<!----------------------------------------------------
public class Bmp {
 
 protected final Log logger = LogFactory.getLog(getClass());
 
 public final static int BITMAPFILEHEADER_SIZE = 14;
 
 public final static int BITMAPINFOHEADER_SIZE = 40;
 /*文件大小*/
 private int size;
 /*文件宽度*/
 private int weight;
 /*文件高度*/
 private int hight;
 /*数据偏移量*/
 private int dataOffset;
 private byte[] current;
 private String filePath;
 
/*get(),set()方法考虑到节省篇幅,请自行设置*/

 public Bmp(){
  
 }
 
 /**
  * 加载bmp文件
  *
  * @param filePath
  * @return
  * @throws IOException
  * @throws BusinessException
  */
 public byte[] loadBmp(String filePath) throws IOException, BusinessException{
  
  this.filePath = filePath;
  this.setParam();
  
  return current;
 }
 
 /**
  * 保存bmp文件
  *
  * @param desPath
  * @throws BusinessException
  * @throws IOException
  */
 public void save(String desPath) throws BusinessException, IOException{
  if(current==null){
   throw new BusinessException("",null);
  }
  
  FileOutputStream fos = new FileOutputStream(desPath);
  fos.write(current,0,current.length);
  fos.flush();
  fos.close();
 }
 
 private void setParam() throws IOException, BusinessException{
  
  /*判断源文件是否是bmp格式,后缀可以是.bmp、.dib、.rle*/
  if(!filePath.contains(".bmp")){
   throw new BusinessException("",null);
  }
  
  FileInputStream  fis = new FileInputStream(filePath);
  /*bmp文件头存储*/
  byte[] fh = new byte[BITMAPFILEHEADER_SIZE];
  fis.read(fh,0,BITMAPFILEHEADER_SIZE);
  /*文件头信息存储*/
  byte[] hi = new byte[BITMAPINFOHEADER_SIZE];
  fis.read(hi,0,BITMAPINFOHEADER_SIZE);
  
  /*设置文件长度*/
  this.size = (((int)fh[5]&0xff)<<24)
            | (((int)fh[4]&0xff)<<16)
             | (((int)fh[3]&0xff)<<8)
              | (int)fh[2]&0xff;
  /*设置文件宽度*/
  this.weight = (((int)hi[7]&0xff)<<24)
            | (((int)hi[6]&0xff)<<16)
             | (((int)hi[5]&0xff)<<8)
              | (int)hi[4]&0xff;
  /*设置文件高度*/
  this.hight = (((int)hi[11]&0xff)<<24)
      | (((int)hi[10]&0xff)<<16)
       | (((int)hi[9]&0xff)<<8)
        | (int)hi[8]&0xff;
  /*设置位图数据阵列起始偏移量*/
  this.dataOffset = (((int)fh[13]&0xff)<<24)
             | (((int)fh[12]&0xff)<<16)
              | (((int)fh[11]&0xff)<<8)
               | (int)fh[10]&0xff;
 
  fis.close();
  loadAll();
 }
 
 private void loadAll() throws IOException{
  
  FileInputStream  fis = new FileInputStream(filePath);
  current = new byte[size];
  
  fis.read(current,0,size);
  
  fis.close();
 }

}
<!----------------------------------
public class NumberConversion {
 
 /**
  * 整形转化为二进制字节
  *
  * @param number  需要转化的数字
  * @param bytes   字节数
  * @return
  */
 public static byte[] intToBytes(int number,int digit){
  
  byte[] byts = new byte[digit];
//  int mask=0xff;
  int basic = 8*(digit-1);
  for(int i=0;i<digit;i++){
   byts[i] = (byte)(number>>>(basic-i*8));
  }
  
  return byts;
  
 }
 
 /**
  *
  * @param bytes
  * @return
  */
 public static int bytesToInt(byte[] b){
  
  int mask=0xff;
  int temp=0;
  int res=0;
  
  for(int i=0;i<4;i++){
         res<<=8;
         temp=b[i]&mask;
         res|=temp;
  }
  return res;

 }
}

posted on 2008-04-03 14:43 zhangxl 阅读(875) 评论(0)  编辑  收藏 所属分类: common

只有注册用户登录后才能发表评论。


网站导航:
 
<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用链接

留言簿(1)

随笔分类(17)

随笔档案(28)

文章分类(30)

文章档案(30)

相册

收藏夹(2)

hibernate

java基础

mysql

xml

关注

压力测试

算法

最新随笔

搜索

  •  

积分与排名

  • 积分 - 94574
  • 排名 - 605

最新评论

阅读排行榜

评论排行榜