package cuiliang.quicker.util; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.pm.ResolveInfo; import android.content.res.AssetFileDescriptor; 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.Parcelable; import android.provider.MediaStore; import android.support.v4.content.FileProvider; import android.util.Log; import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; import cuiliang.quicker.R; /** * https://gist.github.com/Mariovc/f06e70ebe8ca52fbbbe2 * 选择或拍照 */ public class ImagePicker { private static final int DEFAULT_MIN_WIDTH_QUALITY = 1200; // min pixels private static final String TAG = "ImagePicker"; private static final String TEMP_IMAGE_NAME = "tempImage"; public static int minWidthQuality = DEFAULT_MIN_WIDTH_QUALITY; // private static String mCurrentPhotoPath; // // private static File createImageFile(Context context) throws IOException { // // Create an image file name // String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); // String imageFileName = "JPEG_" + timeStamp + "_"; // File storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES); // File image = File.createTempFile( // imageFileName, /* prefix */ // ".jpg", /* suffix */ // storageDir /* directory */ // ); // // // Save a file: path for use with ACTION_VIEW intents // mCurrentPhotoPath = image.getAbsolutePath(); // return image; // } public static Intent getPickImageIntent(Context context) { Intent chooserIntent = null; List<Intent> intentList = new ArrayList<>(); Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); takePhotoIntent.putExtra("return-data", true); Uri uri = FileProvider.getUriForFile(context, "cuiliang.android.fileprovider", getTempFile(context)); takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); intentList = addIntentsToList(context, intentList, pickIntent); intentList = addIntentsToList(context, intentList, takePhotoIntent); if (intentList.size() > 0) { chooserIntent = Intent.createChooser(intentList.remove(intentList.size() - 1), context.getString(R.string.pick_image_intent_text)); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentList.toArray(new Parcelable[]{})); } return chooserIntent; } private static List<Intent> addIntentsToList(Context context, List<Intent> list, Intent intent) { List<ResolveInfo> resInfo = context.getPackageManager().queryIntentActivities(intent, 0); for (ResolveInfo resolveInfo : resInfo) { String packageName = resolveInfo.activityInfo.packageName; Intent targetedIntent = new Intent(intent); targetedIntent.setPackage(packageName); list.add(targetedIntent); Log.d(TAG, "Intent: " + intent.getAction() + " package: " + packageName); } return list; } public static Bitmap getImageFromResult(Context context, int resultCode, Intent imageReturnedIntent) { Log.d(TAG, "getImageFromResult, resultCode: " + resultCode); Bitmap bm = null; File imageFile = getTempFile(context); if (resultCode == Activity.RESULT_OK) { Uri selectedImage; boolean isCamera = (imageReturnedIntent == null || imageReturnedIntent.getData() == null || imageReturnedIntent.getData().toString().contains(imageFile.toString())); if (isCamera) { /** CAMERA **/ selectedImage = Uri.fromFile(imageFile); } else { /** ALBUM **/ selectedImage = imageReturnedIntent.getData(); } Log.d(TAG, "selectedImage: " + selectedImage); bm = getImageResized(context, selectedImage); int rotation = getRotation(context, selectedImage, isCamera); bm = rotate(bm, rotation); } return bm; } private static File getTempFile(Context context) { File imageFile = new File(context.getExternalCacheDir(), TEMP_IMAGE_NAME); imageFile.getParentFile().mkdirs(); return imageFile; } private static Bitmap decodeBitmap(Context context, Uri theUri, int sampleSize) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = sampleSize; AssetFileDescriptor fileDescriptor = null; try { fileDescriptor = context.getContentResolver().openAssetFileDescriptor(theUri, "r"); } catch (FileNotFoundException e) { e.printStackTrace(); } Bitmap actuallyUsableBitmap = BitmapFactory.decodeFileDescriptor( fileDescriptor.getFileDescriptor(), null, options); Log.d(TAG, options.inSampleSize + " sample method bitmap ... " + actuallyUsableBitmap.getWidth() + " " + actuallyUsableBitmap.getHeight()); return actuallyUsableBitmap; } /** * Resize to avoid using too much memory loading big images (e.g.: 2560*1920) **/ private static Bitmap getImageResized(Context context, Uri selectedImage) { // Bitmap bm = null; // int[] sampleSizes = new int[]{5, 3, 2, 1}; // int i = 0; // do { // bm = decodeBitmap(context, selectedImage, sampleSizes[i]); // Log.d(TAG, "resizer: new bitmap width = " + bm.getWidth()); // i++; // } while (bm.getWidth() < minWidthQuality && i < sampleSizes.length); // return bm; int sampleSize = calculateInSampleSize(context, selectedImage, 1200, 1200); Log.d(TAG, "sampleSize = " + sampleSize); return decodeBitmap(context, selectedImage, sampleSize); } public static int calculateInSampleSize(Context context, Uri selectedImage, int reqWidth, int reqHeight) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; AssetFileDescriptor fileDescriptor = null; try { fileDescriptor = context.getContentResolver().openAssetFileDescriptor(selectedImage, "r"); } catch (FileNotFoundException e) { e.printStackTrace(); } BitmapFactory.decodeFileDescriptor( fileDescriptor.getFileDescriptor(), null, options); final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfHeght = height / 2; final int halfWidth = width / 2; while ((halfHeght / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) { inSampleSize *= 2; } } return inSampleSize; } private static int getRotation(Context context, Uri imageUri, boolean isCamera) { int rotation; if (isCamera) { rotation = getRotationFromCamera(context, imageUri); } else { rotation = getRotationFromGallery(context, imageUri); } Log.d(TAG, "Image rotation: " + rotation); return rotation; } private static int getRotationFromCamera(Context context, Uri imageFile) { int rotate = 0; try { //context.getContentResolver().notifyChange(imageFile, null); ExifInterface exif = new ExifInterface(imageFile.getPath()); int orientation = exif.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_270: rotate = 270; break; case ExifInterface.ORIENTATION_ROTATE_180: rotate = 180; break; case ExifInterface.ORIENTATION_ROTATE_90: rotate = 90; break; } } catch (Exception e) { e.printStackTrace(); } return rotate; } public static int getRotationFromGallery(Context context, Uri imageUri) { int result = 0; String[] columns = {MediaStore.Images.Media.ORIENTATION}; Cursor cursor = null; try { cursor = context.getContentResolver().query(imageUri, columns, null, null, null); if (cursor != null && cursor.moveToFirst()) { int orientationColumnIndex = cursor.getColumnIndex(columns[0]); result = cursor.getInt(orientationColumnIndex); } } catch (Exception e) { //Do nothing } finally { if (cursor != null) { cursor.close(); } }//End of try-catch block return result; } private static Bitmap rotate(Bitmap bm, int rotation) { if (rotation != 0) { Matrix matrix = new Matrix(); matrix.postRotate(rotation); Bitmap bmOut = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); return bmOut; } return bm; } }