import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.os.Build;
import android.os.Environment;
import android.support.v4.util.LruCache;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import static android.media.ExifInterface.ORIENTATION_NORMAL;
import static android.media.ExifInterface.ORIENTATION_ROTATE_180;
import static android.media.ExifInterface.ORIENTATION_ROTATE_270;
import static android.media.ExifInterface.ORIENTATION_ROTATE_90;
import static android.media.ExifInterface.TAG_ORIENTATION;
public class ImageFileUtils {
private static final int widthPixels = 480;
private static final int heightPixels = 800;
private static final String PACKAGE_NAME = "com.neobear";
private static LruCache mAppBitmapCache = null;
private static Context mContext;
/**
* 保存bitmap图片到本地
*
* @param filePath
* @param pathName
* @param isClearWhenInit
* @return
*/
public static String saveBitmap(Context context,String filePath, String pathName, boolean isClearWhenInit) {
mContext = context;
Bitmap bitmap = getBitmapWithPath(filePath);
if (bitmap == null) {
return "";
}
String path = "";
if (isClearWhenInit) {
path = getSharePicFile() + pathName;
} else {
path = getUploadPicFile() + pathName;
}
File file = new File(path);
if (file.exists()) {
return path;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
int bitmapSize = baos.toByteArray().length / 2;
Bitmap cacheBitmap = null;
double imageSize = bitmapSize / 1024 / 1024;
// 对可用内存进行判断,来决定压缩策略。。。。需要修改的
if (imageSize >= 1) {
cacheBitmap = resizeImage(bitmap, 1080, path);
} else {
cacheBitmap = resizeImage(bitmap, path);
}
if (cacheBitmap == null) {
path = "";
}
if (cacheBitmap != null && !cacheBitmap.isRecycled()) {
cacheBitmap.recycle();
}
return path;
}
/**
* 文件转换成bitmap
*
* @param path
* @return
*/
private static Bitmap getBitmapWithPath(String path) {
Bitmap bmp = null;
try {
bmp = ImageFileUtils.readNormalPic(path, widthPixels, heightPixels);
} catch (OutOfMemoryError e) {
getBitmapCache().evictAll();
try {
bmp = ImageFileUtils.readNormalPic(path, widthPixels, heightPixels);
} catch (OutOfMemoryError e2) {
}
}
return bmp;
}
private static Bitmap readNormalPic(String filePath, int reqWidth, int reqHeight) {
try {
if (!isExternalStorageMounted()) {
return null;
}
if (!filePath.endsWith(".jpg") && !filePath.endsWith(".gif") && !filePath.endsWith(".png") && !filePath.endsWith(".jpeg"))
filePath = filePath + ".jpg";
boolean fileExist = new File(filePath).exists();
if (!fileExist) {
return null;
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
if (reqHeight > 0 && reqWidth > 0)
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
options.inPurgeable = true;
options.inInputShareable = true;
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
if (bitmap == null) {
// this picture is broken,so delete it
new File(filePath).delete();
return null;
}
if (reqHeight > 0 && reqWidth > 0) {
int[] size = calcResize(bitmap.getWidth(), bitmap.getHeight(), reqWidth, reqHeight);
if (size[0] > 0 && size[1] > 0) {
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, size[0], size[1], true);
if (scaledBitmap != bitmap) {
bitmap.recycle();
bitmap = scaledBitmap;
}
}
}
int exifRotation = ImageFileUtils.getFileExifRotation(filePath);
if (exifRotation != 0) {
Matrix mtx = new Matrix();
mtx.postRotate(exifRotation);
Bitmap adjustedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), mtx, true);
if (adjustedBitmap != bitmap) {
bitmap.recycle();
bitmap = adjustedBitmap;
}
}
return bitmap;
} catch (OutOfMemoryError ignored) {
ignored.printStackTrace();
return null;
}
}
private static synchronized LruCache getBitmapCache() {
if (mAppBitmapCache == null) {
buildCache();
}
return mAppBitmapCache;
}
private static void buildCache() {
int memClass = ((ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
int cacheSize = Math.max(1024 * 1024 * 8, 1024 * 1024 * memClass / 6);
mAppBitmapCache = new LruCache(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getRowBytes() * bitmap.getHeight();
}
};
}
private static boolean isExternalStorageMounted() {
boolean canRead = Environment.getExternalStorageDirectory().canRead();
boolean onlyRead = Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED_READ_ONLY);
boolean unMounted = Environment.getExternalStorageState().equals(
Environment.MEDIA_UNMOUNTED);
return !(!canRead || onlyRead || unMounted);
}
private static 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) {
if (height > reqHeight && reqHeight != 0) {
inSampleSize = (int) Math.floor((double) height / (double) reqHeight);
}
int tmp = 0;
if (width > reqWidth && reqWidth != 0) {
tmp = (int) Math.floor((double) width / (double) reqWidth);
}
inSampleSize = Math.max(inSampleSize, tmp);
}
int roundedSize;
if (inSampleSize <= 8) {
roundedSize = 1;
while (roundedSize < inSampleSize) {
roundedSize <<= 1;
}
} else {
roundedSize = (inSampleSize + 7) / 8 * 8;
}
return roundedSize;
}
private static int[] calcResize(int actualWidth, int actualHeight, int reqWidth, int reqHeight) {
int height = actualHeight;
int width = actualWidth;
float betweenWidth = ((float) reqWidth) / (float) actualWidth;
float betweenHeight = ((float) reqHeight) / (float) actualHeight;
float min = Math.min(betweenHeight, betweenWidth);
height = (int) (min * actualHeight);
width = (int) (min * actualWidth);
return new int[]{width, height};
}
private static int getFileExifRotation(String filePath) {
try {
ExifInterface exifInterface = new ExifInterface(filePath);
int orientation = exifInterface.getAttributeInt(TAG_ORIENTATION,
ORIENTATION_NORMAL);
switch (orientation) {
case ORIENTATION_ROTATE_90:
return 90;
case ORIENTATION_ROTATE_180:
return 180;
case ORIENTATION_ROTATE_270:
return 270;
default:
return 0;
}
} catch (IOException e) {
return 0;
}
}
private static String getSharePicFile() {
return sdCardIsExist() ? getSDAccessPath() + "/file/share/" : "/data/data/" + PACKAGE_NAME + "/files/share/";
}
private static String getUploadPicFile() {
return sdCardIsExist() ? getSDAccessPath() + "/file/" : "/data/data/" + PACKAGE_NAME + "/files/";
}
/**
* 判断sdCard的状态
*
* @author zhangbp
*/
private static boolean sdCardIsExist() {
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}
/**
* 读取sdCard的路径
*
* @author zhangbp
*/
private static String getSDAccessPath() {
if (sdCardIsExist()) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
return Environment.getExternalStorageDirectory().getPath() + "/data/" + PACKAGE_NAME;
} else {
return mContext.getExternalCacheDir() + "";
}
}
return null;
}
private static Bitmap resizeImage(Bitmap bitmap, int w, String filePath) {
Bitmap BitmapOrg = bitmap;
int width = BitmapOrg.getWidth();
int height = BitmapOrg.getHeight();
int newWidth = 0;
int newHeight = 0;
if (width > height) {
newWidth = w;
newHeight = (int) (((float) height) / width * w);
} else {
newWidth = (int) (((float) width) / height * w);
newHeight = w;
}
// calculate the scale
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the Bitmap
matrix.postScale(scaleWidth, scaleHeight);
// if you want to rotate the Bitmap
// matrix.postRotate(readPictureDegree(filePath));
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
height, matrix, true);
resizedBitmap = compressImage(resizedBitmap, filePath);
return resizedBitmap;
}
private static Bitmap resizeImage(Bitmap bitmap, String filePath) {
Bitmap BitmapOrg = bitmap;
int width = BitmapOrg.getWidth();
int height = BitmapOrg.getHeight();
Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
height, null, true);
resizedBitmap = compressImage(resizedBitmap, filePath);
return resizedBitmap;
}
private static Bitmap compressImage(Bitmap image, String filePath) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 80, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 100;
while (baos.toByteArray().length / 1024 > 80) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
if (options >= 10) {
baos.reset();// 重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
options -= 10;// 每次都减少10
} else {
break;
}
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
final BitmapFactory.Options ops = new BitmapFactory.Options();
ops.inJustDecodeBounds = false;
ops.inPreferredConfig = Bitmap.Config.ARGB_8888;
ops.inPurgeable = true;//允许可清除
ops.inInputShareable = true;// 以上options的两个属性必须联合使用才会有效果
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
try {
createFile(filePath);
File file = new File(filePath);
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
bos.flush();
bos.close();
} catch (Exception e) {
e.printStackTrace();
return null;
}
if (image != null && !image.isRecycled()) {
image.recycle();
}
return bitmap;
}
private static boolean createFile(String destFileName) {
File file = new File(destFileName);
if (!file.getParentFile().exists()) {
// 如果目标文件所在的目录不存在,则创建父目录
if (!file.getParentFile().mkdirs()) {
return false;
}
}
if (destFileName.endsWith(File.separator)) {
return false;
}
// 判断目标文件所在的目录是否存在
// 创建目标文件
if (file.exists()) {
return true;
}
try {
return file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}
使用
ImageFileUtils.saveBitmap(context,filepath,filename,false);