package com.donkingliang.imageselector.utils; import android.annotation.SuppressLint; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.media.ExifInterface; import android.net.Uri; import android.os.Environment; import android.os.ParcelFileDescriptor; import android.provider.MediaStore; import android.util.Log; import java.io.File; import java.io.FileDescriptor; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class ImageUtil { /** * 获取缓存图片的文件夹 * * @param context * @return */ public static String getImageCacheDir(Context context) { File file = null; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) { if (VersionUtils.isAndroidQ()) { file = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES); } else { file = context.getExternalCacheDir(); } } if (file == null) { file = context.getCacheDir(); } return file.getPath() + File.separator + "image_select"; } /** * 保存图片 * * @param bitmap * @param path * @param name * @return */ public static String saveImage(Bitmap bitmap, String path, String name) { FileOutputStream b = null; File file = new File(path); if (!file.exists()) { file.mkdirs();// 创建文件夹 } String fileName = path + File.separator + name + ".jpg"; try { b = new FileOutputStream(fileName); bitmap.compress(Bitmap.CompressFormat.JPEG, 75, b);// 把数据写入文件 return fileName; } catch (FileNotFoundException e) { e.printStackTrace(); } finally { try { if (b != null) { b.flush(); b.close(); } } catch (IOException e) { e.printStackTrace(); } } return ""; } public static Bitmap zoomBitmap(Bitmap bm, int reqWidth, int reqHeight) { // 获得图片的宽高 int width = bm.getWidth(); int height = bm.getHeight(); // 计算缩放比例 float scaleWidth = ((float) reqWidth) / width; float scaleHeight = ((float) reqHeight) / height; float scale = Math.min(scaleWidth, scaleHeight); // 取得想要缩放的matrix参数 Matrix matrix = new Matrix(); matrix.postScale(scale, scale); // 得到新的图片 Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true); return newbm; } /** * 根据计算的inSampleSize,得到压缩后图片 * * @param pathName * @param reqWidth * @param reqHeight * @return */ @SuppressLint("NewApi") public static Bitmap decodeSampledBitmapFromFile(Context context, String pathName, int reqWidth, int reqHeight) { int degree = 0; Uri uri = UriUtils.getImageContentUri(context, pathName); ParcelFileDescriptor parcelFileDescriptor = null; FileDescriptor fileDescriptor = null; try { parcelFileDescriptor = context.getContentResolver().openFileDescriptor(uri, "r"); fileDescriptor = parcelFileDescriptor.getFileDescriptor(); ExifInterface exifInterface = null; if (VersionUtils.isAndroidQ()) { exifInterface = new ExifInterface(fileDescriptor); } else { exifInterface = new ExifInterface(pathName); } int result = exifInterface.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED); switch (result) { case ExifInterface.ORIENTATION_ROTATE_90: degree = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: degree = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: degree = 270; break; } } catch (IOException e) { e.printStackTrace(); return null; } try { // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小 final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; if (VersionUtils.isAndroidQ()) { BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options); } else { BitmapFactory.decodeFile(pathName, options); } // 调用上面定义的方法计算inSampleSize值 options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // 使用获取到的inSampleSize值再次解析图片 options.inJustDecodeBounds = false; // options.inPreferredConfig = Bitmap.Config.RGB_565; Bitmap bitmap = null; if (VersionUtils.isAndroidQ()) { bitmap = getBitmapFromUri(context, uri, options); } else { bitmap = BitmapFactory.decodeFile(pathName, options); } parcelFileDescriptor.close(); if (degree != 0) { Bitmap newBitmap = rotateImageView(bitmap, degree); bitmap.recycle(); bitmap = null; return newBitmap; } return bitmap; } catch (OutOfMemoryError error) { Log.e("eee", "内存泄露!"); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 获取Bitmap * * @param context * @param uri * @return */ public static Bitmap getBitmapFromUri(Context context, Uri uri) { return getBitmapFromUri(context, uri, null); } /** * 获取Bitmap * * @param context * @param uri * @return */ public static Bitmap getBitmapFromUri(Context context, Uri uri, BitmapFactory.Options options) { try { ParcelFileDescriptor parcelFileDescriptor = context.getContentResolver().openFileDescriptor(uri, "r"); FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options); parcelFileDescriptor.close(); return image; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 旋转图片 * * @param bitmap * @param angle * @return Bitmap */ public static Bitmap rotateImageView(Bitmap bitmap, int angle) { //旋转图片 动作 Matrix matrix = new Matrix(); matrix.postRotate(angle); // 创建新的图片 return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } /** * 计算inSampleSize,用于压缩图片 * * @param options * @param reqWidth * @param reqHeight * @return */ private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // 源图片的宽度 int width = options.outWidth; int height = options.outHeight; int inSampleSize = 1; if (width > reqWidth && height > reqHeight) { // 计算出实际宽度和目标宽度的比率 int widthRatio = Math.round((float) width / (float) reqWidth); int heightRatio = Math.round((float) height / (float) reqHeight); inSampleSize = Math.max(widthRatio, heightRatio); } return inSampleSize; } public static boolean isEffective(String path) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); return options.outWidth > 0 && options.outHeight > 0; } public static boolean isEffective(Context context, Uri uri) { try { ParcelFileDescriptor parcelFileDescriptor = context.getContentResolver().openFileDescriptor(uri, "r"); FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options); return options.outWidth > 0 && options.outHeight > 0; } catch (IOException e) { e.printStackTrace(); } return false; } /** * 是否是剪切返回的图片 * * @param context * @param path * @return */ public static boolean isCutImage(Context context, String path) { return isCutImage(getImageCacheDir(context), path); } /** * 是否是剪切返回的图片 * * @param dir * @param path * @return */ public static boolean isCutImage(String dir, String path) { if (!StringUtils.isEmptyString(path)) { return path.startsWith(dir); } return false; } /** * 保存拍照的图片 * * @param context * @param uri * @param takeTime 调起相机拍照的时间 */ public static void savePicture(final Context context, final Uri uri, final long takeTime) { new Thread(new Runnable() { @Override public void run() { if (isNeedSavePicture(context, takeTime)) { context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri)); } } }).start(); } /** * 是否需要保存拍照的图片 * * @param context * @return */ private static boolean isNeedSavePicture(Context context, long takeTime) { //扫描图片 Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI .buildUpon().appendQueryParameter("limit","1").build(); ContentResolver mContentResolver = context.getContentResolver(); Cursor mCursor = mContentResolver.query(mImageUri, new String[]{ MediaStore.Images.Media.DATE_ADDED, MediaStore.Images.Media._ID, MediaStore.Images.Media.SIZE}, MediaStore.MediaColumns.SIZE + ">0", null, MediaStore.Files.FileColumns._ID + " DESC"); //读取扫描到的图片 if (mCursor != null && mCursor.getCount() > 0 && mCursor.moveToFirst()) { //获取图片时间 long time = mCursor.getLong(mCursor.getColumnIndex(MediaStore.Images.Media.DATE_ADDED)); int id = mCursor.getInt(mCursor.getColumnIndex(MediaStore.Images.Media._ID)); if (String.valueOf(time).length() < 13) { time *= 1000; } mCursor.close(); // 如果照片的插入时间大于相机的拍照时间,就认为是拍照图片已插入 return time + 1000 < takeTime; } return true; } }