这里讲图片的简单处理,主要是讲图片的压缩和缓存。
/**
* 将输入流转化为字节数组
*
* @param inputStream
* @return
* @throws IOException
*/
public static byte[] streamToByteArray(InputStream inputStream) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
outputStream.flush();
//关掉资源
inputStream.close();
//返回字节数组
return outputStream.toByteArray();
}
/**
* 压缩图片
*
* @param data 图片的字节数组
* @param destWidth 目标的宽度
* @param destHeight 目标的高度
* @return 压缩后的图片
*/
public static Bitmap zipBitmap(byte[] data, int destWidth, int destHeight) {
//创建图片参数
BitmapFactory.Options options = new BitmapFactory.Options();
//设置只加载边框
options.inJustDecodeBounds = true;
//第一次采样,加载图片的边框
BitmapFactory.decodeByteArray(data, 0, data.length, options);
//获得原始图片的高和宽、
int width = options.outWidth;
int height = options.outHeight;
//计算压缩比例
int sampleSize = 1;
while (width / sampleSize > destWidth || height / sampleSize > destHeight) {
sampleSize *= 2;
}
//重新设置参数,加载边框
options.inJustDecodeBounds = false;
//压缩比例
options.inSampleSize = sampleSize;
//图片格式
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
//第二次采样,获得压缩后的图片
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
return bitmap;
}
public static final int MAX_SIZE = 10 * 1024 * 1024;
//一级缓存
private static LruCache mMemoryCache= new LruCache<>(MAX_SIZE);;
/**
* md5加密方法
* @param url
* @return
*/
public static String md5(String url) {
try {
//获得md5算法对象
MessageDigest digest = MessageDigest.getInstance("md5");
//进行md5加密
byte[] digest1 = digest.digest(url.getBytes());
//将加密后的字节转化为16进制的字符串
StringBuilder sb = new StringBuilder();
for (int i = 0; i < digest1.length; i++) {
sb.append(Integer.toHexString(digest1[i]));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
/**
* 将图片保存到一级缓冲中
*
* @param url
* @param bitmap
*/
public static void saveToMemory(String url, Bitmap bitmap) {
String md5 = md5(url);
mMemoryCache.put(md5, bitmap);
}
/**
* 从一级缓冲中读取图片
*
* @param url
* @return
*/
public static Bitmap getFromMemory(String url) {
return mMemoryCache.get(md5(url));
}
二级缓存:
DiskLruCache //二级缓存
private static DiskLruCache mDiskCacheDiskLruCache.open(getCacheDir(context), getVersionCode(context), 1, MAX_SIZE * 5);
/**
* 获得磁盘缓存目录
*
* @param context
* @return
*/
public static File getCacheDir(Context context) {
//判断SDcard是否存在
if (Environment.MEDIA_MOUNTED == Environment.getExternalStorageState()) {
//返回SDcard缓存目录
return context.getExternalCacheDir();
}
//返回当前应用程序的缓存目录
return context.getCacheDir();
}
/**
* 获得程序版本号
*
* @param context
* @return
*/
public static int getVersionCode(Context context) {
int code = 0;
try {
code = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode;
} catch (Exception e) {
e.printStackTrace();
}
return code;
}
/**
* 保存到二级缓存中
*
* @param url
* @param bitmap
*/
public static void saveToDisk(String url, Bitmap bitmap) {
try {
//获得Editor对象
DiskLruCache.Editor editor = mDiskCache.edit(md5(url));
//获得输出流
OutputStream outputStream = editor.newOutputStream(0);
//将图片保存到流中
boolean compress = bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
//判断是否保存成功
if (compress) {
//提交保存
editor.commit();
} else {
//退出保存
editor.abort();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 从二级缓存中读取图片
*
* @param url
* @return
*/
public static Bitmap readFromDisk(String url) {
try {
//获得图片的快照
DiskLruCache.Snapshot snapshot = mDiskCache.get(md5(url));
if (snapshot != null) {
//获得输入流
InputStream inputStream = snapshot.getInputStream(0);
//将流转化为图片
return BitmapFactory.decodeStream(inputStream);
}
} catch (Exception e) {
}
return null;
}
package com.example.doimageview;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Environment;
import android.renderscript.ScriptGroup;
import android.util.Log;
import android.util.LruCache;
import com.jakewharton.disklrucache.DiskLruCache;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* Created by Lenovo on 2017/5/8.
*/
public class LoadImageView {
public interface OnLoadImageVIewListener {
void OnLoadIageView(Bitmap bitmap);
}
private OnLoadImageVIewListener mListener;
public void showImageView(String url, int width, int height, OnLoadImageVIewListener listener) {
this.mListener = listener;
new MyTask(width, height).execute(url);
}
public void showImageView(String url, OnLoadImageVIewListener listener) {
this.mListener = listener;
new MyTask().execute(url);
}
class MyTask extends AsyncTask {
//压缩的目标宽度和高度
private int mWidth;
private int mHeight;
public MyTask() {
}
public MyTask(int mWidth, int mHeight) {
this.mHeight = mHeight;
this.mWidth = mWidth;
}
@Override
protected Bitmap doInBackground(String... params) {
try {
//首先从一级缓存中 读取图片
Bitmap bitmap = getFromMemory(params[0]);
//如果一级缓存中没有该图片就从二级缓存中读取
if (bitmap == null) {
bitmap = readFromDisk(params[0]);
//如果二级缓存中没有该图片就从网络中读取
if (bitmap == null) {
//得到URL
URL url = new URL(params[0]);
//获得连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//得到输入流
InputStream inputStream = conn.getInputStream();
//得到图片
if (mWidth == 0 || mHeight == 0) {
//不用压缩图片,把输入流转化为图片
bitmap = BitmapFactory.decodeStream(inputStream);
} else {
//压缩图片
bitmap = zipBitmap(streamToByteArray(inputStream), mWidth, mHeight);
}
//关闭流
inputStream.close();
//从网络加载图片后保存到一级缓存和二级缓存中
saveToMemory(params[0], bitmap);
saveToDisk(params[0],bitmap);
}else{
//如果二级缓存不为空,就保存到一级缓存中
saveToMemory(params[0],bitmap);
}
}
//如果不为空,就直接返回图片
return bitmap;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (mListener != null) {
mListener.OnLoadIageView(bitmap);
}
}
}
/**
* 将输入流转化为字节数组
*
* @param inputStream
* @return
* @throws IOException
*/
public static byte[] streamToByteArray(InputStream inputStream) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
outputStream.flush();
//关掉资源
inputStream.close();
//返回字节数组
return outputStream.toByteArray();
}
/**
* 压缩图片
*
* @param data 图片的字节数组
* @param destWidth 目标的宽度
* @param destHeight 目标的高度
* @return 压缩后的图片
*/
public static Bitmap zipBitmap(byte[] data, int destWidth, int destHeight) {
//创建图片参数
BitmapFactory.Options options = new BitmapFactory.Options();
//设置只加载边框
options.inJustDecodeBounds = true;
//第一次采样,加载图片的边框
BitmapFactory.decodeByteArray(data, 0, data.length, options);
//获得原始图片的高和宽、
int width = options.outWidth;
int height = options.outHeight;
//计算压缩比例
int sampleSize = 1;
while (width / sampleSize > destWidth || height / sampleSize > destHeight) {
sampleSize *= 2;
}
//重新设置参数,加载边框
options.inJustDecodeBounds = false;
//压缩比例
options.inSampleSize = sampleSize;
//图片格式
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
//第二次采样,获得压缩后的图片
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
return bitmap;
}
public static final int MAX_SIZE = 10 * 1024 * 1024;
//一级缓存
private static LruCache mMemoryCache;
//二级缓存
private static DiskLruCache mDiskCache;
/**
* 初始化缓存
*
* @param context
*/
public static void initCache(Context context) {
mMemoryCache = new LruCache<>(MAX_SIZE);
try {
mDiskCache = DiskLruCache.open(getCacheDir(context), getVersionCode(context), 1, MAX_SIZE * 5);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获得磁盘缓存目录
*
* @param context
* @return
*/
public static File getCacheDir(Context context) {
//判断SDcard是否存在
if (Environment.MEDIA_MOUNTED == Environment.getExternalStorageState()) {
//返回SDcard缓存目录
return context.getExternalCacheDir();
}
//返回当前应用程序的缓存目录
return context.getCacheDir();
}
/**
* 获得程序版本号
*
* @param context
* @return
*/
public static int getVersionCode(Context context) {
int code = 0;
try {
code = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode;
} catch (Exception e) {
e.printStackTrace();
}
return code;
}
/**
* 保存到二级缓存中
*
* @param url
* @param bitmap
*/
public static void saveToDisk(String url, Bitmap bitmap) {
try {
//获得Editor对象
DiskLruCache.Editor editor = mDiskCache.edit(md5(url));
//获得输出流
OutputStream outputStream = editor.newOutputStream(0);
//将图片保存到流中
boolean compress = bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
//判断是否保存成功
if (compress) {
//提交保存
editor.commit();
} else {
//退出保存
editor.abort();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 从二级缓存中读取图片
*
* @param url
* @return
*/
public static Bitmap readFromDisk(String url) {
try {
//获得图片的快照
DiskLruCache.Snapshot snapshot = mDiskCache.get(md5(url));
if (snapshot != null) {
//获得输入流
InputStream inputStream = snapshot.getInputStream(0);
//将流转化为图片
return BitmapFactory.decodeStream(inputStream);
}
} catch (Exception e) {
}
return null;
}
/**
* md5加密方法
* @param url
* @return
*/
public static String md5(String url) {
try {
//获得md5算法对象
MessageDigest digest = MessageDigest.getInstance("md5");
//进行md5加密
byte[] digest1 = digest.digest(url.getBytes());
//将加密后的字节转化为16进制的字符串
StringBuilder sb = new StringBuilder();
for (int i = 0; i < digest1.length; i++) {
sb.append(Integer.toHexString(digest1[i]));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
/**
* 将图片保存到一级缓冲中
*
* @param url
* @param bitmap
*/
public static void saveToMemory(String url, Bitmap bitmap) {
String md5 = md5(url);
mMemoryCache.put(md5, bitmap);
}
/**
* 从一级缓冲中读取图片
*
* @param url
* @return
*/
public static Bitmap getFromMemory(String url) {
return mMemoryCache.get(md5(url));
}
}