Android图片压缩

图片BitmapFactory压缩

Android中提供的对图像的解析BitmapFactory类。直接上代码,以作为记录.

/** * 根据普通需要显示的宽和高进行压缩 * * @param path * @param width * @param height * @return */    protected Bitmap decodeSampledBitmapFromPath(String path, int width,            int height) {        // 获取图片的宽和高,并不把图片加载到内存当中        BitmapFactory.Options options = new BitmapFactory.Options();        // true表示禁止系统加载图像到内存        options.inJustDecodeBounds = true;        BitmapFactory.decodeFile(path, options);        options.inSampleSize = caculateInSampleSize(options, width, height);        // 使用获取到的inSampleSize再次解析图片        options.inJustDecodeBounds = false;        Bitmap bitmap = BitmapFactory.decodeFile(path, options);        return bitmap;    }    /** * 根据需求的宽和高以及实际的宽和高计算SampleSize * * @param options * @param width * @param height * @return */    private int caculateInSampleSize(Options options, int reqWidth,            int reqHeight) {        int width = options.outWidth;        int height = options.outHeight;        int inSampleSize = 1;        // 得到一个比例        if (width > reqWidth || height > reqHeight) {            int widthRadio = Math.round(width * 1.0f / reqWidth);            int heightRadio = Math.round(height * 1.0f / reqHeight);            inSampleSize = Math.max(widthRadio, heightRadio);        }        return inSampleSize;    }

图片缓存LruCache

在过去,我们经常会使用一种非常流行的内存缓存技术的实现,即软引用或弱引用 (SoftReference or WeakReference)。但是现在已经不再推荐使用这种方式了,因为从 Android 2.3 (API Level 9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用和弱引用变得不再可靠。下面是使用LruCache的例子

private LruCache<String, Bitmap> mMemoryCache;  @Override  protected void onCreate(Bundle savedInstanceState) {      // 获取到可用内存的最大值,使用内存超出这个值会引起OutOfMemory异常。     // LruCache通过构造函数传入缓存值,以KB为单位。     int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);      // 使用最大可用内存值的1/8作为缓存的大小。     int cacheSize = maxMemory / 8;      mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {          @Override          protected int sizeOf(String key, Bitmap bitmap) {              // 重写此方法来衡量每张图片的大小,默认返回图片数量。             return value.getRowBytes() * value.getHeight();          }      };  }  public void addBitmapToMemoryCache(String key, Bitmap bitmap) {      if (getBitmapFromMemCache(key) == null) {          mMemoryCache.put(key, bitmap);      }  }  public Bitmap getBitmapFromMemCache(String key) {      return mMemoryCache.get(key);  }

在中高配置的手机当中,这大概会有4兆(32/8)的缓存空间。一个全屏幕的 GridView 使用4张 800x480分辨率的图片来填充,则大概会占用1.5兆的空间(800*480*4)。因此,这个缓存大小可以存储2.5页的图片。

当向 ImageView 中加载一张图片时,首先会在 LruCache 的缓存中进行检查。如果找到了相应的键值,则会立刻更新ImageView ,否则开启一个后台线程来加载这张图片。

public void loadBitmap(int resId, ImageView imageView) {      final String imageKey = String.valueOf(resId);      final Bitmap bitmap = getBitmapFromMemCache(imageKey);      if (bitmap != null) {          imageView.setImageBitmap(bitmap);      } else {          imageView.setImageResource(R.drawable.image_placeholder);          BitmapWorkerTask task = new BitmapWorkerTask(imageView);          task.execute(resId);      }  } 

BitmapWorkerTask 还要把新加载的图片的键值对放到缓存中。

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {      // 在后台加载图片。     @Override      protected Bitmap doInBackground(Integer... params) {          final Bitmap bitmap = decodeSampledBitmapFromResource(                  getResources(), params[0], 100, 100);          addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);          return bitmap;      }  }  

图片的压缩及内存缓存这样的方案,在实战中经常使用到,而且OOM问题有效的得到解决。

更多相关文章

  1. Android(安卓)Studio的.gitignore以及gitignore无效的解决
  2. 「抄底 Android(安卓)内存优化 3」 —— JVM 内存管理
  3. Android清除本地数据缓存代码案例
  4. Android(安卓)调用相册 拍照 实现系统控件缩放 切割图片
  5. 短视频app开源源码android 给图片加文字、图片水印
  6. Android中向服务器上传图片
  7. Android:如何显示网络图片
  8. Android(安卓)图片设置圆角
  9. android背景选择器selector用法汇总

随机推荐

  1. Android的Bitmap处理大图片解决方法
  2. Android解析如何获取SDCard 内存
  3. Android(安卓)N进入分屏代码分析二
  4. Android(安卓)EventBus简单使用
  5. 图片常用的控件
  6. activity 设置Theme.Dialog View高度
  7. apk 反编译源码 资源文件
  8. Android编程心得-JSON使用心得(二)
  9. Android实现网络加载图片点击大图后浏览
  10. Android防止过快点击造成多次事件