Android实际开发中。在载入大量图片的时候。比方ViewPager、GridView、ListView中,载入了大量的比較大图片就easy出现OOM(内存溢出)的异常,这是由于一个应用的最大内存使用仅仅有16M。超过了这个值。就会出现OOM。

所以我们实际开发中,要想避免OOM出现就要对对应的图片进行压缩处理。

本文即使用了BitmapFactory和BitmapFactory.Option这两个类,对图片进行对应的尺寸压缩处理。

经測试,成功攻克了未压缩图片之前出现的OOM异常。

实现效果图:

本Demo使用的图片大小为2M左右(压缩曾经)。

我压缩图片之前:

我这里将压缩的代码凝视掉了:

执行结果:

进行压缩处理后的图片:

压缩后图片大小为:

大约为98KB

执行结果:

源码:

布局文件:

activity_main:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" > <ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" >
</ListView> </RelativeLayout>

list_item.xml:

<?

xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" > <ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> <TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"/> </LinearLayout>

MainActivity:

package com.android_bitmapcompressdemo;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView; public class MainActivity extends Activity {
private ListView listView;
private MyAdapter adapter;
private int[] items = new int[] { R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,
R.drawable.pc, R.drawable.pc };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); listView = (ListView) findViewById(R.id.listView);
adapter = new MyAdapter(this, items);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}

ListView适配器:MyAdapter:

package com.android_bitmapcompressdemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView; public class MyAdapter extends BaseAdapter {
private int[] items = new int[] {};
private Context context;
private String TAG = "zhongyao";
private Bitmap bitmap = null; public MyAdapter(Context context, int[] items) {
this.context = context;
this.items = items;
} @Override
public int getCount() {
return items.length;
} @Override
public Object getItem(int position) {
return items[position];
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.imageView = (ImageView) convertView.findViewById(R.id.imageView);
holder.textView = (TextView) convertView.findViewById(R.id.textView); convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
} bitmap = BitmapCompressTools.decodeSampledBitmapFromResource(
context.getResources(), R.drawable.pc, 100, 100);
Log.d(TAG, "压缩之后的图片大小为:" + bitmap.getByteCount());
holder.imageView.setImageBitmap(bitmap);
holder.textView.setText("图片"+position); return convertView;
} class ViewHolder {
ImageView imageView;
TextView textView;
}
}

BitmapCompressTools(压缩工具类):

package com.android_bitmapcompressdemo;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory; public class BitmapCompressTools {
public static Bitmap decodeSampledBitmapFromResource(Resources res,
int resId, int reqWidth, int reqHeight) { // 给定的BitmapFactory设置解码的參数
final BitmapFactory.Options options = new BitmapFactory.Options();
// 从解码器中获取原始图片的宽高。这样避免了直接申请内存空间
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options); // Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight); // 压缩完后便能够将inJustDecodeBounds设置为false了。
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
} /**
* 指定图片的缩放比例
*
* @param options
* @param reqWidth
* @param reqHeight
* @return
*/ public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// 原始图片的宽、高
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1; // if (height > reqHeight || width > reqWidth) {
// //这里有两种压缩方式。可供选择。
// /**
// * 压缩方式二
// */
// // final int halfHeight = height / 2;
// // final int halfWidth = width / 2;
// // while ((halfHeight / inSampleSize) > reqHeight
// // && (halfWidth / inSampleSize) > reqWidth) {
// // inSampleSize *= 2;
// // }
//
/**
* 压缩方式一
*/
// 计算压缩的比例:分为宽高比例
final int heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
// } return inSampleSize;
}
}

达到了预期效果。可是写到这里滑动ListView的时候,还是会有些卡顿,有这方面解决经验的能够给我留言讨论。

源码已上传到资源中,可到我的资源中下载。

Android BitmapFactory图片压缩处理(大位图二次採样压缩处理)的更多相关文章

  1. Android开发之大位图二次採样压缩处理(源码分享)

    图片有各种形状和大小.在很多情况下这些图片是远远大于我们的用户界面(UI)且占领着极大的内存空间,假设我们不正确位图进行压缩处理,我们的程序会发生内存泄露的错误. MainActivity的代码 pa ...

  2. Android 中图片压缩分析(上)

    作者: shawnzhao,QQ音乐技术团队一员 一.前言 在 Android 中进行图片压缩是非常常见的开发场景,主要的压缩方法有两种:其一是质量压缩,其二是下采样压缩. 前者是在不改变图片尺寸的情 ...

  3. Android Camera开发系列(上)——Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片

    Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 最近也是在搞个破相机,兼容性那叫一个不忍直视啊,于是自己翻阅了一些基本的资料,自己实现了一 ...

  4. Android中图片压缩(质量压缩和尺寸压缩)

    关于Android 图片压缩的学习: 自己总结分为质量压缩和像素压缩.质量压缩即:将Bitmap对象保存到对应路径下是所占用的内存减小,但是当你重新读取压缩后的file为Bitmap时,它所占用的内存 ...

  5. Android笔记(二十八) Android中图片之简单图片使用

    用户界面很大程度上决定了APP是否被用户接收,为了提供友好的界面,就需要在应用中使用图片了,Android提供了丰富的图片处理功能. 简单使用图片 使用Drawable对象 为Android应用增加了 ...

  6. Android的图片压缩并上传

    Android开发中上传图片很常见,一般为了节省流量会进行压缩的操作,本篇记录一下压缩和上传的方法. 图片压缩的方法 : import java.io.ByteArrayOutputStream; i ...

  7. Android 图片设置圆角 方法之二

    Android中经常会遇到对图片进行二次处理,例如加圆角,或者显示圆形图片.接下来我们再介绍一种方法. 首先, 自定义ImageView: android:id="@+id/iv" ...

  8. Android bitmap图片处理

    一.View转换为Bitmap         在Android中所有的控件都是View的直接子类或者间接子类,通过它们可以组成丰富的UI界面.在窗口显示的时候Android会把这些控件都加载到内存中 ...

  9. Android中图片的三级缓存策略

    在开发过程中,经常会碰到进行请求大量的网络图片的样例.假设处理的不好.非常easy造成oom.对于避免oom的方法,无非就是进行图片的压缩.及时的回收不用的图片.这些看似简单可是处理起来事实上涉及的知 ...

随机推荐

  1. BZOJ2555 SubString 【后缀自动机 + LCT】

    题目 懒得写背景了,给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支持这些操作. 输入 ...

  2. Python之面向对象:封装

    1.封装的概念 将对象的数据与操作数据的方法相结合,通过方法将对象的数据与实现细节保护起来,就称为封装.外界只能通过对象的方法访问对象,因此封装同时也实现了对象的数据隐藏. 在使用面向对象的封装特性时 ...

  3. Intellij热部署插件JRebel

    Intellij热部署插件JRebel 安装JRebel 激活JRebel 相关设置 Intellij热部署插件JRebel 项目需求,一直用eclipse的我,也要改用IDEA了,一开始,很不习惯. ...

  4. Jury Compromise(poj 1015)

    描述在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定.陪审团是由法官从公众中挑选的.先随机挑选n个人作为陪审团的候选人,然后再从这n个人中选m人组成陪审团.选m人的办法是: 控方和辩方会根据对候选 ...

  5. ZOJ1608 Two Circles and a Rectangle

    Time Limit: 2 Seconds      Memory Limit: 65536 KB Give you two circles and a rectangle, your task is ...

  6. final、finalize()、finally、static

    一.final final的三种情况: 1.变量 1)对于基本类型,final使数值恒定不变:而对于对象引用,final使引用恒定不变,即一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象, ...

  7. c# automapper 使用

    一.最简单的用法 有两个类User和UserDto 1 public class User 2 { 3 public int Id { get; set; } 4 public string Name ...

  8. 基于 Intraweb 和 JQuery 的开发套件

    基于 Intraweb 和 JQuery 的开发套件 http://www.cgdevtools.com/ 开发速度无敌,界面也非常美. 我的web短板终于解决了.....!!!!..!!! 做一个小 ...

  9. MQ 分拆Json数据包然后上传

    public void UploadInsurHistory() { using (IDbConnection connection = ConnConfig.DmsConnection) { IDb ...

  10. 转载——分享一个html+js+ashx+easyui+ado.net权限管理系统

    EasyUI.权限管理 这是个都快被搞烂了的组合,但是easyui的确好用,权限管理在项目中的确实用.一直以来博客园里也不少朋友分享过,但是感觉好的要不没源码,要不就是过度设计写的太复杂看不懂,也懒得 ...