概述
- Android中使用Bitmap加载图片很容易造成OOM,所以要在加载的时候对其做相应的处理。
- Bitmap的压缩格式
- ALPHA_8
表示8位Alpha位图,即A=8,一个像素点占用1个字节,它没有颜色,只有透明度 - ARGB_4444
表示16位ARGB位图,即A=4,R=4,G=4,B=4,一个像素点占4+4+4+4=16位,2个字节 - ARGB_8888
表示32位ARGB位图,即A=8,R=8,G=8,B=8,一个像素点占8+8+8+8=32位,4个字节 - RGB_565
表示16位RGB位图,即R=5,G=6,B=5,它没有透明度,一个像素点占5+6+5=16位,2个字节
- ALPHA_8
- 了解了Bitmap的压缩格式,这样我们就知道图片加载到手机上所占的内存大小了。
- 图片的 宽 * 高 * 每个像素所占的大小 = 图片的总大小。
在不进行设置压缩格式的情况下,默认使用 ARGB_8888,每个像素占4个字节。
创建工程BitmapTest,布局文件中一个按钮,一个ImageView。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_marginTop="10dp"
android:layout_centerHorizontal="true"
android:id="@+id/iv_scenery"
android:layout_width="300dp"
android:layout_height="300dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="直接加载图片"
android:id="@+id/btn_load"
android:layout_below="@+id/iv_scenery"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp" />
</RelativeLayout>
创建一个assets文件夹,放入了一个2560*1600分辨率的a.jpg图片。
MainActivity代码如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_load;
private ImageView iv_scenery;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_load = (Button) this.findViewById(R.id.btn_load);
iv_scenery = (ImageView) this.findViewById(R.id.iv_scenery);
btn_load.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_load:
try {
//拿到图片对应的输入流
InputStream inputStream = getResources().getAssets().open("a.jpg");
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
Log.d("直接加载bitmap","大小:"+bitmap.getByteCount()+"b ,--"+(double)bitmap.getByteCount()/1024/1024+"M --,宽度:"
+bitmap.getWidth()+"--,高度:"+bitmap.getHeight());
//设置给imageview
iv_scenery.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
运行程序,点击 直接加载图片按钮。图片就会加载上去。Log如下。
可见直接加载所占的内存为15.625M。也验证了我们计算图片所占内存大小的方法。
2560 * 1600 * 4 = 16384000 。
如果对图片的效果要求不是很高,可以设置图片的格式为RGB_565,这样就可以省一半内存了。
布局文件中新加个按钮 ,
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="压缩格式后加载"
android:id="@+id/btn_compress"
android:layout_centerHorizontal="true"
android:layout_below="@+id/btn_load"
MainActivity中对其进行监听。
private Button btn_compress;
btn_compress = (Button) this.findViewById(R.id.btn_compress);
btn_compress.setOnClickListener(this);
case R.id.btn_compress:
try {
//拿到图片对应的输入流
InputStream inputStream = getResources().getAssets().open("a.jpg");
//首先,如果对图片质量要求不高,可以设置图片的压缩格式为RGB_565
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
//矩阵
Rect rect = new Rect();
//获取到bitmap对象
Bitmap bitmap2 = BitmapFactory.decodeStream(inputStream, rect, options);
Log.d("压缩格式为RGB_565加载bitmap2", "大小:" +bitmap2.getByteCount()+"b ,--"+ (double) bitmap2.getByteCount() / 1024 / 1024 +
"M--,宽度:" + bitmap2.getWidth() + "--,高度:" + bitmap2.getHeight());
//设置给imageview
iv_scenery.setImageBitmap(bitmap2);
}catch (IOException e) {
e.printStackTrace();
}
break;
运行程序点击 压缩格式后加载 按钮,发现图片大小比之前刚好小了一半。Log如下:
但是即使这样,图片的大小还是很大的,所以我们在加载的时候要对其进行缩放。
布局文件中添加 压缩并缩放后加载 按钮。
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="压缩并缩放后加载"
android:id="@+id/btn_scale"
android:layout_below="@+id/btn_compress"
android:layout_centerHorizontal="true"
/>
MainActivity中对按钮进行监听,图片等比例缩放,这样子就不会影响图片的效果。
private Button btn_scale;
btn_scale = (Button) this.findViewById(R.id.btn_scale);
btn_scale.setOnClickListener(this);
case R.id.btn_scale:
try {
//拿到图片对应的输入流
InputStream inputStream = getResources().getAssets().open("a.jpg");
//首先,如果对图片质量要求不高,可以设置图片的压缩格式为RGB_565
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
//设置为true,表示解析Bitmap对象,该对象不占内存
options.inJustDecodeBounds = true;
//矩阵
Rect rect = new Rect();
BitmapFactory.decodeStream(inputStream,rect,options);
//设置缩放比例
options.inSampleSize = computeScale(options, iv_scenery);
Log.d("比例",options.inSampleSize+"");
//拿到比例之后要把options.inJustDecodeBounds重新设置为false
options.inJustDecodeBounds = false;
//获取到bitmap对象
Bitmap bitmap3 = BitmapFactory.decodeStream(inputStream,rect,options);
Log.d("压缩并缩放后加载bitmap3","大小:"+bitmap3.getByteCount()+"b ,--"+(double)bitmap3.getByteCount()/1024/1024+"M--,宽度:"+bitmap3.getWidth()+"--,高度:"+bitmap3.getHeight());
iv_scenery.setImageBitmap(bitmap3);
}catch (IOException e) {
e.printStackTrace();
}
break;
//计算缩放比例
private int computeScale(BitmapFactory.Options options, ImageView iv_scenery) {
int scaleSize = 1;
if (options.outWidth > iv_scenery.getWidth() || options.outHeight > iv_scenery.getHeight()){
int widthScale = Math.round((float) options.outWidth / (float) iv_scenery.getWidth());
int heightScale = Math.round((float) options.outHeight / (float) iv_scenery.getHeight());
if (widthScale >= heightScale){
scaleSize = widthScale;
}else {
scaleSize = heightScale;
}
}
return scaleSize;
}
运行程序,点击 压缩并缩放后加载 按钮,发现图片已经小很多了。Log如下:
这样图片的大小就只有0.5M了,就不容易造成OOM。
以上就是Bitmap加载大图方式方法。如有错误请指出,谢谢!
最后
以上就是飘逸舞蹈为你收集整理的Android开发Bitmap加载大图的全部内容,希望文章能够帮你解决Android开发Bitmap加载大图所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复