场景一
当拍了一张照片需要显示在屏幕上的时候,需要对图片进行压缩然后显示
1.需要先把图片转化为Bitmap对象,根据像素要求压缩Bitmap
2.压缩了Bitmap后需要确认图片的方向,然后调整方向
/**
* 将图片转化成bitmap,根据大小显示压缩bitmap,且根据图片选择将bitmap旋转
*
* @param strImageSource 图片真实绝对路径地址
* @param nLimitSize 限制图片的大小 传1024比较多
*/
public static Bitmap comPressFile2Bitmap(String strImageSource, int nLimitSize) {
Bitmap rotatedNewbitmap = null;
try {
Log.v("ddrb", "strImageSource = " + strImageSource);
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inDither = true; // 避免图片抖动
opts.inPurgeable = true; // 内存可以被回收
opts.inJustDecodeBounds = true;//如果该 值设为true那么将不返回实际的bitmap,也不给其分配内存空间这样就避免内存溢出了
//1.从文件中读出图片参数
BitmapFactory.decodeFile(strImageSource, opts);
//2.根据图片大小与限制的大小,计算出合适的采样率
opts.inSampleSize = calulateInSampleSize(opts, nLimitSize);
//3.获取压缩后的bitmap
opts.inJustDecodeBounds = false;//是时候来获取bitmap了
Bitmap bitmap = BitmapFactory.decodeFile(strImageSource, opts);
if (bitmap != null) {
//4.把图片旋转为正的方向
int degree = getExifOrientation(strImageSource);
rotatedNewbitmap = rotaingImageView(degree, bitmap);
} else {
return null;
}
} catch (Exception e) {
LogUtil.e("GsdImageDecoder","comPressFile2Bitmap", e);
}
return rotatedNewbitmap;
}
// 这个函数会对图片的大小进行判断
static int calulateInSampleSize(BitmapFactory.Options opts, int limitSize) {
int height = opts.outHeight;
int width = opts.outWidth;
int sampleSize = 1;
while ((height / sampleSize) >= limitSize && (width / sampleSize) >= limitSize) {
sampleSize *= 2;
}
LogUtil.d("cjw", "最大像素限制:"
+ limitSize
+ "||原始大小宽/高:"
+ width
+ "/"
+ height
+ "||最后的压缩比:"
+ sampleSize);
return sampleSize;
}
/**
* 获取图片的角度
*/
public static int getExifOrientation(String filepath) {
int degree = 0;
ExifInterface exif = null;
try {
exif = new ExifInterface(filepath);
} catch (IOException ex) {
}
if (exif != null) {
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
if (orientation != -1) {
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
}
}
return degree;
}
/**
* 旋转图片
*
* @param angle 选择角度
* @return Bitmap
*/
public static Bitmap rotaingImageView(int angle, Bitmap bitmap) {
if (angle == 0) {
return bitmap;
}
//旋转图片 动作
Matrix matrix = new Matrix();
matrix.postRotate(angle);
System.out.println("angle2=" + angle);
// 创建新的图片
Bitmap resizedBitmap =
Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix,
true);
//matirx肯定不为null, resizedBitmap和bitmap不为同一对象
if (bitmap != null && !bitmap.isRecycled()) {
bitmap.recycle();
}
return resizedBitmap;
}
场景二
1.在图片上传的时候,有时候需要把原图进行压缩,这种压缩一定会影响到图片的质量
/**
* 将本地路径下的图片 根据指定质量压缩率 压缩到缓存文件夹 + 当前系统时间.jpg的File中
*
* @param localPath 本地图片路径
* @param ratio 指定的压缩率 默认为80
* @return 经过质量压缩后的File文件
*/
public static File compressPic2File(String localPath, int ratio) {
//1.拿到压缩后的Bitmap
Bitmap bitmap = comPressFile2Bitmap(localPath, ALBUM_IMG_MAX_SIZE);
if (null == bitmap) {
return null;
}
int compressRatio = 80; //给个默认值
if (ratio > 0 && ratio <= 100) {
compressRatio = ratio;
}
FileOutputStream fos = null;
File targetFile = null;
try {
String fileName = String.valueOf(System.currentTimeMillis()).concat(".jpg");
//2.创建缓存文件夹下 指定文件名为fileName的文件 并最终返回给调用者
String path = FolderUtil.getCacheFilePath(fileName);
if (TextUtils.isEmpty(path)) {
return null;
}
targetFile = new File(path);
//3.将压缩图片流写入targetFile中
fos = new FileOutputStream(targetFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, compressRatio, fos); //质量压缩
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
CloseUtil.close(fos);
CloseUtil.recycle(bitmap);
}
return targetFile;
}
/**
* Created by magical.zhang on 2016/10/29.
* Description : 回收工具类
*/
public class CloseUtil {
/**
* 关闭实现Closeable接口的对象
* 代码复用 提高可读性
*/
public static void close(Closeable closeable) {
if (null != closeable) {
try {
closeable.close();//此接口只有一个关闭流的方法
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 关闭多个流
*/
public static void close(Closeable... closeables) {
for (Closeable closeable : closeables) {
close(closeable);
}
}
/**
* 回收Bitmap
*/
public static void recycle(Bitmap bitmap) {
if (null != bitmap && !bitmap.isRecycled()) {
bitmap.recycle();
}
}
}