zoukankan      html  css  js  c++  java
  • android自带的处理Bitmap out Memory 的处理,我仅仅是改变了些写法成为自己用的东西

    每天上万次的启动载入证明这个载入是不错的;

    第三方的载入框架非常多,推荐使用成熟框架,比方大家都知道的ImageLoad等,

    这里的仅仅供学习;

    我也曾在一个菜谱的项目里写过载入手机相冊图片的,只是当时写的不好,有空我会再写一个,这个项目里用这个jar包,上万次的载入偶尔看到三星的报两三个OOM还好

    缓存管理在这里

    http://blog.csdn.net/intbird/article/details/38338713

    图片处理在这里

    http://blog.csdn.net/intbird/article/details/38338811

    界面回收图片在这里

    http://blog.csdn.net/intbird/article/details/19905549

    工具Jar包在这里说明:

    http://pan.baidu.com/s/1dDtOZbr


    集成的一个[缓存和图片资源载入]工具类,BitmapHelper,CacheHelper,,

    下载地址http://pan.baidu.com/s/1dDtOZbr

    用法://注,必须导入Android-support-v4包.

    1,在应用初始化时初始化缓存文件夹:

    //(sd下主目录,拍照目录,图片缓存目录)

    //主文件夹一般为应用的getString()中的AppName;

    CacheHelper.initCache("Intbird");

    //经常使用的一些方法


    2,初始化图片帮助类

    BitmapHelper bitmapHelper=new BitmapHelper(context,R.drawable.ic_launcher,R.drawable.ic_launcher);
    BitmapHelper bitmapHelper=new BitmapHelper(context);


    //终于载入实现类

    BitmapHelper.LoadOptions options=new BitmapHelper.LoadOptions();

    //一些简单的图片处理的封装,在其它用到的地方在说明



    3 外部帮助类,封装程序中遇到图片的地方

    public static class ImageOptions implements Serializable{
      		public int imageType;
      		public int cropWidth;
      		public int cropHeight;
      		public int displayWidth;
      		public int displayHeight;
      		public int qulity;
      		public int maxKb=-1;
      		public boolean isNeedRoteAnge=false;
      		public boolean isTumbnail;
      		public ImageUploadType uploadType;
      		public ImageCropType cropType;
      		//已知载入方法
      		public LoadBitmapFinish finish;
      		public DisplayImageOptions displayOption;
      		public ImageLoadingListener listener;
      	}


    4,普通快捷记载单个图片

    bitmapHelper.loadBitmap(BitmapHelper.IMG_TYPE_FILE, fileUrl, iv,options.displayWidth,options.displayHeight,options.finish);

    //内部真实实现方式,能够构造这个很多其它的功能

    bitmapHelper.loadBitmap(loadOption);

    //finish 

    LoadBitmapFinish 在失败和成功后都会返回,失败时bitmap返回为空

    5,对于列表载入实现

    //在载入的前面加个true,means is used in listView;

    bitmap.loadBitmap(true,BitmapHelper.IMG_TYPE_WEB, value, v,200,200,null);

    //内部真实实现方式,能够构造这个很多其它的功能

    bitmapHelper.loadBitmap(loadOption);

    6,演示样例

    //单个 

    bitmapHelper.loadBitmap(BitmapHelper.IMG_TYPE_FILE, fileUrl, iv,options.displayWidth,options.displayHeight,options.finish);

    //列表

    @Override
    public void setViewImage(ImageView v, String value) {
    <span style="white-space:pre">	</span>bitmap.loadBitmap(true,BitmapHelper.IMG_TYPE_WEB, value, v,200,200,null);
    }
    	

    //停止载入

    bitmapHelper.finishLoadSingle();//单个
    adapter.finishLoad();//列表

    public void finishLoad(){
    if(bitmap!=null)
    bitmap.finishLoadForList();
    }

    7,载入效果





    1.0.0大致实现方式:版本号已经过多次改动和项目中不同手机收集到的错误信息改动过,请使用云盘上最新的版本号以保证项目能够正常使用(最新的是我在项目里使用的),下面代码仅供学习....

    /** 
     * @author intbird@163.com 
     * @time 20140606 
     */ 
    package com.intbird.utils;
    
    import java.lang.ref.WeakReference;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Bitmap.Config;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.PorterDuff.Mode;
    import android.graphics.PorterDuffXfermode;
    import android.graphics.Rect;
    import android.graphics.drawable.BitmapDrawable;
    import android.graphics.drawable.Drawable;
    import android.media.ThumbnailUtils;
    import android.os.AsyncTask;
    import android.widget.ImageView;
    
    public class BitmapHelper {
    	
    	private CacheManager cacheManager;
    	
    	public static final int IMG_TYPE_RES=0;
    	public static final int IMG_TYPE_WEB=1;
    	public static final int IMG_TYPE_FILE=3;
    	
    	private Bitmap bmpHolder=null;
    	private Bitmap bmpNoImg=null;
    	
    	public BitmapHelper(Context context,int loadingId,int loadNoId){
    		cacheManager=CacheManager.getInstance();
    		bmpHolder=BitmapFactory.decodeResource(context.getResources(),loadingId);
    		bmpNoImg=BitmapFactory.decodeResource(context.getResources(),loadNoId);
    	}
    	
    	/**
    	 * 载入图片
    	 * @param type 网络文件,本地文件,还是资源文件
    	 * @param fileUrl url
    	 * @param imageView 控件
    	 * @param width 要获取的指定高度
    	 * @param height 要获取的指定宽度
    	 */
    	public void commonLoadBitmap(int type,String fileUrl,ImageView imageView,int width,int height){
    		//内存和文件里没有图片,又一次获取;
    		Bitmap bmp=cacheManager.getBitmapFromCache(fileUrl);
    		if(bmp!=null){
    			imageView.setImageBitmap(bmp);
    		}
    		else{
    			switch(type){
    			case IMG_TYPE_WEB:
    				loadMultiBitmapFromWeb(fileUrl, imageView,width,height);
    				break;
    			case IMG_TYPE_FILE:
    				imageView.setImageBitmap(getBitmapFormFile(	fileUrl, width, height, true));
    				break;
    			case IMG_TYPE_RES:
    				imageView.setImageResource(Integer.parseInt(fileUrl));
    				break;
    			}
    		}
    	}
    	
    	/**
    	 * 设置ImageView为获取指定文件地址的指定高度指定宽度的图片; 
    	 * @param fileUrl 文件地址
    	 * @param reqWidth 目标宽度
    	 * @param reqHeight 目标高度
    	 * @return bitmap
    	 */
    	public Bitmap loadSingleBitmapFromFile(String fileUrl,ImageView iv,int reqWidth,int reqHeight){
    		BitmapFactory.Options options=new BitmapFactory.Options();
    		options.inJustDecodeBounds=true;
    		options.inSampleSize=calculateInSampleSize(options, reqWidth, reqHeight);
    		BitmapFactory.decodeFile(fileUrl,options);
    		options.inJustDecodeBounds=false;
    		Bitmap bmp=BitmapFactory.decodeFile(fileUrl,options);
    		if(iv!=null) iv.setImageBitmap(bmp);
    		return 	bmp;
    	}
    	/**
    	 * 设置ImageView为须要载入的一张网络图片;
    	 * @param webUrl
    	 * @param imageView
    	 * @param width
    	 * @param heigth
    	 */
    	public void loadSingleBitmapFromWeb(String webUrl,ImageView imageView,int width,int heigth){
    		BitmapHelper.BitmapWorkerSingleTask task=new BitmapWorkerSingleTask(imageView);
    		task.execute(webUrl,width+"",heigth+"");
    	}
    
    	/**
    	 * adapter中载入图片
    	 * @param fileUrl 图片地址
    	 * @param imageView 图片控件
    	 * @param width 要得到的宽度
    	 * @param height 要的到的高度
    	 */
    	public void loadMultiBitmapFromWeb(String fileUrl, ImageView imageView,int width,int height) {
    		
    	    if (cancelPotentialWork(fileUrl, imageView)) {
    	    	
    	        final BitmapMultiWorkerTask task = new BitmapMultiWorkerTask(imageView);
    	        
    	        final AsyncDrawable asyncDrawable =new AsyncDrawable(bmpHolder, task);
    	        
    	        imageView.setImageDrawable(asyncDrawable);
    	        
    	        task.execute(fileUrl,width+"",height+"");
    	    }
    	}
    	
    	/**
    	 * 从网络中载入一个须要的Bitmap;
    	 * @param webUrl
    	 * @param reqWidth
    	 * @param reqHeight
    	 * @return
    	 */
    	public Bitmap getBitmapFormWeb(String webUrl,int reqWidth,int reqHeight){
    		BitmapFactory.Options options=new BitmapFactory.Options();
    		options.inJustDecodeBounds=true;
    		options.inSampleSize=calculateInSampleSize(options, reqWidth, reqHeight);
    		return ConnInternet.loadBitmapFromNet(webUrl, options);
    	}
    
    	/**
    	 * 将图片文件转换成bitmap
    	 * 
    	 * @param fileUrl
    	 *            图片文件路径
    	 * @param width
    	 *            宽度
    	 * @param height
    	 *            高度
    	 * @param isThumbnail
    	 *            是否依据高宽生成缩略图
    	 * @return
    	 */
    	public Bitmap getBitmapFormFile(String fileUrl, int width, int height,
    			boolean isThumbnail) {
    		Bitmap bitmap=loadSingleBitmapFromFile(fileUrl,null, width, height);
    		// 生成固定尺寸的缩略图
    		if (isThumbnail) {
    			bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
    					ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
    		}
    		cacheManager.addBitmapToCache(fileUrl, bitmap);
    		return bitmap;
    	}
    
    	/**
    	 * 转换图片成圆形
    	 * 
    	 * @param bitmap 
    	 * @return
    	 */
    	public static Bitmap changeBitmapToRound(Bitmap bitmap) {
    		if(bitmap==null)
    			return null;
    		int width = bitmap.getWidth();
    		int height = bitmap.getHeight();
    		float roundPx;
    		float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
    		if (width <= height) {
    			roundPx = width / 2;
    			left = 0;
    			top = 0;
    			right = width;
    			bottom = width;
    			height = width;
    			dst_left = 0;
    			dst_top = 0;
    			dst_right = width;
    			dst_bottom = width;
    		} else {
    			roundPx = height / 2;
    			float clip = (width - height) / 2;
    			left = clip;
    			right = width - clip;
    			top = 0;
    			bottom = height;
    			width = height;
    			dst_left = 0;
    			dst_top = 0;
    			dst_right = height;
    			dst_bottom = height;
    		}
    	
    		Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
    		Canvas canvas = new Canvas(output);
    	
    		final int color = 0xff424242;
    		final Paint paint = new Paint();
    		final Rect src = new Rect((int) left, (int) top, (int) right,
    				(int) bottom);
    		final Rect dst = new Rect((int) dst_left, (int) dst_top,
    				(int) dst_right, (int) dst_bottom);
    		paint.setAntiAlias(true);// 设置画笔无锯齿
    	
    		canvas.drawARGB(0, 0, 0, 0); // 填充整个Canvas
    		paint.setColor(color);
    	
    		// 下面有两种方法画圆,drawRounRect和drawCircle
    		// canvas.drawRoundRect(rectF, roundPx, roundPx, paint);//
    		// 画圆角矩形,第一个參数为图形显示区域。第二个參数和第三个參数各自是水平圆角半径和垂直圆角半径。
    		canvas.drawCircle(roundPx, roundPx, roundPx, paint);
    	
    		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));// 设置两张图片相交时的模式,參考http://trylovecatch.iteye.com/blog/1189452
    		canvas.drawBitmap(bitmap, src, dst, paint); // 以Mode.SRC_IN模式合并bitmap和已经draw了的Circle
    		return output;
    	}
    
    	/**
    	 * 计算所需大小的图片 的压缩比例
    	 * @param options
    	 * @param reqWidth 所需宽度
    	 * @param reqHeight 所需高度
    	 * @return 压缩比例
    	 */
    	public  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;
    	    	}
    		}
    		return inSampleSize;
    	}
    
    	/**
    	 * 检查启动的任务
    	 * @param fileUrl 文件路径
    	 * @param imageView 目标控件
    	 * @return 是否開始载入任务
    	 */
    	private  boolean cancelPotentialWork(String fileUrl, ImageView imageView) {
    	
    	    final BitmapMultiWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
    	    
    	    if (bitmapWorkerTask != null) {
    	    	
    	        String bitmapUrl = bitmapWorkerTask.fileUrl;
    	        if (bitmapUrl!=null&&bitmapUrl != fileUrl) {
    	        	
    	            bitmapWorkerTask.cancel(true);
    	            return true;
    	        }
    	        
    	        else {
    	            return false;
    	        }
    	    }
    	    return true;
    	}
    
    	/**
    	 * 获取该图片控件中的载入任务
    	 * @param imageView
    	 * @return 返回该任务
    	 */
    	private  BitmapMultiWorkerTask getBitmapWorkerTask(ImageView imageView) {
    		   if (imageView != null) {
    		       final Drawable drawable = imageView.getDrawable();
    		       if (drawable instanceof AsyncDrawable) {
    		           final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
    		           return asyncDrawable.getBitmapWorkerTask();
    		       }
    		    }
    		    return null;
    	}
    	private class AsyncDrawable extends BitmapDrawable {
    	    private final WeakReference<BitmapMultiWorkerTask> bitmapWorkerTaskReference;
    	    @SuppressWarnings("deprecation")
    		public AsyncDrawable(Bitmap bitmap,BitmapMultiWorkerTask bitmapWorkerTask) {
    	        super(bitmap);
    	        bitmapWorkerTaskReference =new WeakReference<BitmapMultiWorkerTask>(bitmapWorkerTask);
    	    }
    	    public BitmapMultiWorkerTask getBitmapWorkerTask() {
    	        return bitmapWorkerTaskReference.get();
    	    }
    	}
    	private class BitmapMultiWorkerTask extends AsyncTask<String, Void, Bitmap> {
    		private WeakReference<ImageView> imageViewReference;
    		private String fileUrl;
    		public BitmapMultiWorkerTask(ImageView imageView){
    			imageViewReference=new WeakReference<ImageView>(imageView);
    		}
    		@Override
    		protected Bitmap doInBackground(String... params) {
    			fileUrl=params[0];
    			int reqWidth=Integer.valueOf(params[1]);
    			int reqHeight=Integer.valueOf(params[2]);
    			Bitmap bitmap=getBitmapFormWeb(fileUrl,reqWidth,reqHeight);
    			return bitmap;
    		}
    		
    		@Override
    	    protected void onPostExecute(Bitmap bitmap) {
    	      
    	        if (isCancelled()) {
    	            bitmap = null;
    	        }
    	        
    	        if (imageViewReference != null) {
    	            final ImageView imageView = imageViewReference.get();
    	            
    	            final BitmapMultiWorkerTask bitmapWorkerTask =getBitmapWorkerTask(imageView);
    	           
    	            if (this == bitmapWorkerTask && imageView != null) {
    	            	
    	            	if(bitmap!=null){
    	            		imageView.setImageBitmap(bitmap);
    	            		cacheManager.addBitmapToCache(fileUrl, bitmap);
    	            	}
    	            
    	            	else{
    	            		imageView.setImageBitmap(bmpNoImg);
    	            	}
    	            }
    	        }
    	    }
    	}
    	/**
    	 * 异步载入一张图片
    	 * @author intbird@163.com
    	 *
    	 */
    	private class BitmapWorkerSingleTask extends AsyncTask<String, Void, Bitmap>{
    		private WeakReference<ImageView> imageViewReference;
    		private String fileUrl="";
    		public BitmapWorkerSingleTask(ImageView imageView){
    			imageViewReference=new WeakReference<ImageView>(imageView);
    		}
    		@Override
    		protected Bitmap doInBackground(String... params) {
    			fileUrl=params[0];
    			int reqWidth=Integer.valueOf(params[1]);
    			int reqHeight=Integer.valueOf(params[2]);
    			Bitmap bitmap=getBitmapFormWeb(fileUrl,reqWidth,reqHeight);
    			return bitmap;
    		}
    		@Override
    		protected void onPostExecute(Bitmap bitmap) {
    			 if (imageViewReference != null) {
    		            final ImageView imageView = imageViewReference.get();
    		            if (imageView != null) {
    		            	if(bitmap!=null){
    		            		imageView.setImageBitmap(bitmap);
    		            	}
    	            	   else{
    			            	  imageView.setImageBitmap(bmpNoImg);
    			            }
    		            }
    		    }
    		}
    	}
    }
    

  • 相关阅读:
    三、sersync+rsync实现服务器文件实时同步
    二、Linux实时同步软件之inotify
    一、rsync基础原理
    Samba实战
    DHCP企业实战
    NTP服务器企业实战
    Vsftpd服务器原理及部署
    Python的五大数据类型的作用、定义方式、使用方法,两种交互式方式,格式化输出的三种方式练习。
    pycharm快捷键,变量,字符串,类型的操作方法
    python基础归纳练习 python两种方式,垃圾回收机制,小数整池,数字类型,字符串类型。
  • 原文地址:https://www.cnblogs.com/jhcelue/p/6906772.html
Copyright © 2011-2022 走看看