一般情况下,异步从网络加载图片我们通过url然后得到该图片的输入流InputStream,拿到InputStream为了避免图片体积和分辨率过大造成OOM的问题,会将图片压缩之后再显示在UI上,此时一般会使用如下类似的压缩代码
private Bitmap decodeBitmap(String url,InputStream is) throws IOException {
if (is == null) {
return null;
}
BitmapFactory.Options options = new BitmapFactory.Options();
//设置该属性可以不占用内存,并且能够得到bitmap的宽高等属性,此时得到的bitmap是空
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);
int inSampleSize = calculateInSampleSize(options,getReqWidth(),getReqHeight());
//设置计算得到的压缩比例
options.inSampleSize = 4;//这里简单做一下宽高都缩小4倍操作,项目中应计算得到压缩比例
//设置为false,确保可以得到bitmap != null
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
return bitmap;
}
但是这样操作之后,你会发现在上述第十四行处得到的bitmap是null。这个问题发生的原因就在于之前已经读取过一次InputStream流了,所以再次通过InputStream流得到bitmap的时候就为空了,因为InputStream流只能被读取一次,下次读取就为空了。
解决办法就是在得到InputStream之后,先将InputStream转化为字节数组,然后在使用decodeByteArray方法解析图片,先将InputStream流转为byte数组
private byte[] inputStream2ByteArr(InputStream inputStream) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int len = 0;
while ( (len = inputStream.read(buff)) != -1) {
outputStream.write(buff, 0, len);
}
inputStream.close();
outputStream.close();
return outputStream.toByteArray();
}
然后在调用如下代码实现解析图片的操作
private Bitmap decodeBitmap(String url,InputStream is) throws IOException {
if (is == null) {
return null;
}
BitmapFactory.Options options = new BitmapFactory.Options();
//设置该属性可以不占用内存,并且能够得到bitmap的宽高等属性,此时得到的bitmap是空
options.inJustDecodeBounds = true;
byte[] data = inputStream2ByteArr(is);//将InputStream转为byte数组,可以多次读取
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
//设置计算得到的压缩比例
options.inSampleSize = 4;
//设置为false,确保可以得到bitmap != null
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
return bitmap;
}