package l.test1.util;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.BitmapFactory.Options;public class BitmapUtil {private static final Size ZERO_SIZE = new Size(0,0);private static final Options OPTIONS_GET_SIZE = new Options();private static final Options OPTIONS_DECODE = new Options();static{OPTIONS_GET_SIZE.inJustDecodeBounds = true;}public static Size getBitMapSize(String path){File file = new File(path);if(file.exists()){InputStream in = null;try{in = new FileInputStream(file);BitmapFactory.decodeStream(in, null, OPTIONS_GET_SIZE);return new Size(OPTIONS_GET_SIZE.outWidth,OPTIONS_GET_SIZE.outHeight);} catch (FileNotFoundException e) {return ZERO_SIZE;}finally{closeInputStream(in);}}return ZERO_SIZE;}public static Bitmap createBitmap(String path,int width,int height){File file = new File(path);if(file.exists()){InputStream in = null;try {in = new FileInputStream(file);Size size = getBitMapSize(path);if(size.equals(ZERO_SIZE)){return null;}int scale = 1;int a = size.getWidth() / width;int b = size.getHeight() / height;scale = Math.max(a, b);synchronized (OPTIONS_DECODE) {OPTIONS_DECODE.inSampleSize = scale;Bitmap bitMap =  BitmapFactory.decodeStream(in,null,OPTIONS_DECODE);return bitMap;}} catch (FileNotFoundException e) {e.printStackTrace();} finally{closeInputStream(in);}}return null;}public static void destory(Bitmap bitmap){if(null != bitmap && !bitmap.isRecycled()){bitmap.recycle();bitmap = null;}}private static void closeInputStream(InputStream in) {if(null != in){try {in.close();} catch (IOException e) {e.printStackTrace();}}}}class Size{private int width,height;Size(int width,int height){this.width = width;this.height = height;}public int getWidth() {return width;}public int getHeight() {return height;}}
  
  
  

package l.test1.util;import java.util.HashMap;import java.util.HashSet;import java.util.LinkedList;import java.util.Map;import java.util.Set;import java.util.Stack;import android.graphics.Bitmap;/** * Bitmap工具类,缓存用过的指定数量的图片,使用此工具类,不再需要手动管理Bitmap内存 * 原理: * 用一个队列保存使用Bitmap的顺序,每次使用Bitmap将对象移动到队列头 * 当内存不够,或者达到制定的缓存数量的时候,回收队列尾部图片 * 保证当前使用最多的图片得到最长时间的缓存,提高速度 * @author liaoxingliao * */public final class BitMapLRU {private static int CACHE_BYTE_SIZE = 10*1024*1024; //缓存10M图片private static int CACHE_SIZE = 2000; //缓存图片数量 private static int byteSize = 0;private static final byte[] LOCKED = new byte[0];private static final LinkedList<String> CACHE_ENTRIES = //此对象用来保持Bitmap的回收顺序,保证最后使用的图片被回收new LinkedList<String>(){private static final long serialVersionUID = 1L;@Overridepublic void addFirst(String object) {while(remove(object));super.addFirst(object);}};private static final Stack<QueueEntry> TASK_QUEUE = new Stack<QueueEntry>();//线程请求创建图片的队列private static final Set<String> TASK_QUEUE_INDEX = new HashSet<String>();//保存队列中正在处理的图片的key,有效防止重复添加到请求创建队列private static final Map<String,Bitmap> IMG_CACHE_INDEX = new HashMap<String,Bitmap>();//缓存Bitmap 通过图片路径,图片大小static{//初始化创建图片线程,并等待处理new Thread(){{setDaemon(true);}public void run() {while(true) {synchronized (TASK_QUEUE) {if(TASK_QUEUE.isEmpty()) {try {TASK_QUEUE.wait();} catch (InterruptedException e) {e.printStackTrace();}}}QueueEntry entry = TASK_QUEUE.pop();String key = createKey(entry.path,entry.width,entry.height);TASK_QUEUE_INDEX.remove(key);createBitmap(entry.path, entry.width, entry.height);}}}.start();}/** * 创建一张图片 如果缓存中已经存在,则返回缓存中的图,否则创建一个新的对象,并加入缓存 * 宽度,高度,为了缩放原图减少内存的,如果输入的宽,高,比原图大,返回原图 * @param path图片物理路径 (必须是本地路径,不能是网络路径) * @param width需要的宽度 * @param height需要的高度 * @return */public static Bitmap createBitmap(String path, int width, int height) {Bitmap bitMap = null;try{while(CACHE_ENTRIES.size() >= CACHE_SIZE || byteSize >= CACHE_BYTE_SIZE) {destoryLast();}bitMap = useBitmap(path, width, height);if( bitMap != null && !bitMap.isRecycled()){return bitMap;//4294967296}bitMap = BitmapUtil.createBitmap(path, width, height);if(bitMap == null) {  //可能不是有效的图片..return null; }byteSize += (bitMap.getRowBytes() * bitMap.getHeight());String key = createKey(path,width,height);synchronized (LOCKED) {IMG_CACHE_INDEX.put(key, bitMap);CACHE_ENTRIES.addFirst(key);}}catch(OutOfMemoryError err) {System.out.println("OOM:" + byteSize);destoryLast();return createBitmap(path, width, height);}return bitMap;}/** * 设置缓存图片数量 如果输入负数,会产生异常 * @param size */public static void setCacheSize(int size) {if(size <=0 ){throw new RuntimeException("size :"+size);}while(size < CACHE_ENTRIES.size()){destoryLast();}CACHE_SIZE = size;}/** * 加入一个图片处理请求到图片创建队列 * @param path图片路径(本地) * @param width图片宽度 * @param height图片高度 */public static void addTask(String path, int width, int height) {QueueEntry entry = new QueueEntry();entry.path = path;entry.width = width;entry.height = height;synchronized (TASK_QUEUE) {while(TASK_QUEUE.size() > 20) {QueueEntry e =  TASK_QUEUE.lastElement();TASK_QUEUE.remove(e);TASK_QUEUE_INDEX.remove(createKey(e.path, e.width, e.height));}String key = createKey(path,width,height);if(!TASK_QUEUE_INDEX.contains(key) && !IMG_CACHE_INDEX.containsKey(key)){TASK_QUEUE.push(entry);TASK_QUEUE_INDEX.add(key);TASK_QUEUE.notify();}}}public static void cleanTask() {synchronized (TASK_QUEUE) {TASK_QUEUE_INDEX.clear();TASK_QUEUE.clear();}}// 将图片加入队列头private static Bitmap useBitmap(String path,int width,int height) {Bitmap bitMap = null;String key = createKey(path,width,height);synchronized (LOCKED) {bitMap = IMG_CACHE_INDEX.get(key);if(null != bitMap){CACHE_ENTRIES.addFirst(key);}}return bitMap;}// 回收最后一张图片private static void destoryLast() {synchronized (LOCKED) {if(!CACHE_ENTRIES.isEmpty()) {String key = CACHE_ENTRIES.removeLast();if(key.length() > 0) {Bitmap bitMap = IMG_CACHE_INDEX.remove(key);if(bitMap != null) {bitMap.recycle();byteSize -= (bitMap.getRowBytes() * bitMap.getHeight());bitMap = null;}}}}}// 创建键private static String createKey(String path,int width,int height) {if(null == path || path.length() == 0) {return "";}return path+"_"+width+"_"+height;}// 队列缓存参数对象static class QueueEntry{public String path;public int width;public int height;}}


更多相关文章

  1. 下载显示网路图片的例子
  2. android 处理图片之--bitmap处理
  3. android Bimtap 各种图片处理方法、图片特效
  4. Android如何实现图片轮播
  5. 图片拖动功能实现
  6. Android平台上实现图片的缩放,圆角,倒影效果
  7. android读取图片

随机推荐

  1. 用 NodeJS 充分利用多核 CPU 的资源[每日
  2. IDEA + Spring Boot 的三种热加载方案,看
  3. 用 cURL 请求测试 ETag 浏览器缓存[每日
  4. 69.批量创建mysql用户
  5. 香~Spring Boot 应用也可以有注册中心。
  6. 香~Spring Boot 应用也可以有配置中心。
  7. W3C TPAC 大会上的 Service workers 内容
  8. Linux性能优化(八)——网络测试工具
  9. Spring 中的事件机制,芳芳用过都说好~
  10. Swagger 自动生成 Dubbo 服务的接口文档,