浏览 2878 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-01-11
以下是转换的具体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; } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |