java下24bit位图转化为16bit位图实现

关于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;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值