第三方的加载框架很多,推荐使用成熟框架,比如大家都知道的ImageLoad等,
这里的只供学习;
我也曾在一个菜谱的项目里写过加载手机相册图片的,不过当时写的不好,有空我会再写一个,这个项目里用这个jar包
缓存管理在这里
http://blog.youkuaiyun.com/intbird/article/details/38338713
图片处理在这里
http://blog.youkuaiyun.com/intbird/article/details/38338811
界面回收图片在这里
http://blog.youkuaiyun.com/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);
}
//停止加载
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);
}
}
}
}
}
}