前面已经介绍了如何解析C++的结构体数据,因为.dat根据C++的数据类型的不同,所以有不同的解析方式,比如解析单字节,双字节和四个字节的方式是不一样的。今天我们讨论的是android如何解析C++传递过来的图片数据。这个问题困扰了我将近一个星期的时间,各种数组越界异常和空指针异常的问题层出不穷,为了使以后的人少走弯路,现将源码记录下来,供各位参考。
package com.ht.masteel.utils;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
/****
* 解析.dat文件,并将文件转化成bitmap
*
* @author htao
*
*/
public class BitmapUtils {
private static FileInputStream fis;
/****
* 该方法用于获取.dat的字节数组
*
* @param filePath
* 文件路径
* @param fileName
* 文件名
* @return .dat文件的字节数组
*/
public static byte[] getBitmapArray(String filePath, String fileName,
int pWidth, int pHeight) {
byte[] newArrays = new byte[pHeight * pWidth];//定义一个数组用于存放图片的字节
// 定义一个字节数组,用于存放.dat文件中的字节码// 其中740 byte是头信息//752头信息
byte[] byteArrays = new byte[pHeight * pWidth + 752];
// path文件路径,fileName为文件名
File file = new File(filePath, fileName);
if (file.exists()) {
System.out.println("文件存在");
try {
fis = new FileInputStream(file);
// 循环的去读file文件中的内容
int len = 0;
byte[] buffer = new byte[fis.available()];// 每次读取的字节数为1kb
int k = 0;
while ((len = fis.read(buffer)) != -1) {
// 将一个数组添加到另一个数组中
for (int i = 0; i < buffer.length; i++) {
byteArrays[k] = buffer[i];
k++;
}
}
System.out.println("k=" + k);
// newArrays = new byte[pWidth * pHeight];
int j = 0;
for (int i = 752; i < byteArrays.length; i++) {
newArrays[j] = byteArrays[i];
j++;
}
System.out.println("newArray.length:" + newArrays.length);
// for (int i = 200; i < 400; i++) {
// System.out.println("byteArray[" + i + "]:" + byteArrays[i]);
// }
return newArrays;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}else{
System.out.println("文件不存在");
}
return null;
}
/***
* 将字节数组转换成bitmap
*
* @param picW
* 文件图片的宽度
* @param picH
* 文件图片的高度
* @return 灰度图像
*/
public static Bitmap createBitmap(int pWidth, int pHeight, String filePath,
String fileName) {
byte[] newArrays=getBitmapArray(filePath, fileName, pWidth, pHeight);
//System.out.println("newArrays.lengthkkk:"+newArrays.length);
//交換字节的顺序
// byte[] tempArray = exchangeRows(newArrays, pWidth, pHeight);
// System.out.println("byteArray.length=" + byteArrays.length);
if (newArrays == null || pWidth <= 0 || pHeight <= 0) {
System.out.println("byteArrays is null");
return null;
}
// 使用8位来保存图片
Bitmap bitmap = Bitmap.createBitmap(pWidth, pHeight, Config.RGB_565);
int pixels[] = new int[pWidth * pHeight];
System.out.println("pixels.length=" + pixels.length);
for (int i = 0; i < pixels.length; ++i) {// 1360*1024=1392640
// 关键代码,生产灰度图
pixels[i] = newArrays[i] * 256 * 256 + newArrays[i] * 256
+ newArrays[i] + 0xFF000000;
}
//设置像素的值
bitmap.setPixels(pixels, 0, pWidth, 0, 0, pWidth, pHeight);
// newArrays = null;
// pixels = null;
File file = new File(filePath, "help2.jpg");
try {
//将bitmap图像压缩保存
bitmap.compress(Bitmap.CompressFormat.JPEG, 100,
new FileOutputStream(file));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("bitmap:" + bitmap);
return bitmap;
}
/****
* 将二进制数组转换成bitmap对象,并保存
*
* @param filePath
* 文件路径
* @param fileName
* 文件名
* @return 返回bitmap
*/
/*
* public static Bitmap bytes2Bitmap(String filePath, String fileName) {
* int[] byteArrs = getBitmapArray(filePath, fileName); if (byteArrs ==
* null) { return null; } else { // 如果图像数据不能被解码返回为空 Bitmap bitmap =
* BitmapFactory.decodeByteArray(byteArrs, 0, byteArrs.length); File file =
* new File(filePath, "world.jpg"); try { if (bitmap == null) {
* System.out.println("bitmap为空"); } else {
* bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new
* FileOutputStream(file)); return bitmap; }
*
* } catch (FileNotFoundException e) { // TODO Auto-generated catch block
* e.printStackTrace(); }
*
* } return null;
*
* }
*/
/****
* * 交换首尾的顺序
*
* @param byteArray
* byteArray 字节数组
* @param pWidth
* 数组的宽度
* @param pHeight
* 数组的高度
* @return 交换后的字节数组
*/
public static byte[] exchangeRows(byte[] byteArray, int pWidth, int pHeight) {
/****
* 步骤 1,将一维数组转换成二维数组 2,交换二维数组的首尾行 3,将交换后的二维数组转换成一维数组
*/
byte[][] tempArray = new byte[pHeight][pWidth];// 定义一个二维数组,用来存放一维数组的byte数据
int k = 0;
for (int rol = 0; rol < pHeight; rol++) {// 行
for (int col = 0; col < pWidth; col++) {// 列
tempArray[rol][col] = byteArray[k];
k++;
}
}
// 定义一个一维数组,用来存放颠倒后的二维数组
int i = 0;
byte[] oneDimenArr = new byte[pHeight * pWidth];
// 交换二维数组的首尾行
for (int rol = pHeight - 1; rol >= 0; rol--) {
for (int col = 0; col < pWidth; col++) {
oneDimenArr[i] = tempArray[rol][col];
i++;
}
}
return oneDimenArr;
}
}
作者:htao 写于安徽大学
解析后的图片如下: