注意:三星手機中會出現照片旋轉,進而引起返回數據時出現的activity生命週期被重置的問題,在清單文件中添加 一下代碼就可以:
android:configChanges="orientation|keyboardHidden|screenSize"
/** * 從相冊選擇原生的照片(不裁切) */ public static void selectPhotoFromGallery(BrandCarBaseActivity activity, int requestCode) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_PICK); //從所有圖片中進行選擇 intent.setType("image/*"); activity.startActivityForResult(intent, requestCode); } /** * 拍取照片不裁切 */ public static void selectPhotoFromTake(BrandCarBaseActivity activity, String fiePath, int requestCode) { Intent intent = new Intent(); //設置Action爲拍照 intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); //將拍取的照片保存到指定URI intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(fiePath))); activity.startActivityForResult(intent, requestCode); } /** * 採樣率(等比)壓縮 * 根據路徑獲得圖片並壓縮,返回bitmap用於顯示 * * @param filePath 圖片路徑 * @param reqHeight 照片壓縮後的height * @param reqWidth 照片壓縮後的width * @return */ public static Bitmap getCompressBitmap(String filePath, int reqHeight, int reqWidth) { final BitmapFactory.Options options = new BitmapFactory.Options(); if (filePath != null) { options.inJustDecodeBounds = true; BitmapFactory.decodeFile(filePath, options); options.inSampleSize = caculateInSampleSize(options, reqHeight, reqWidth); options.inPreferredConfig = Bitmap.Config.RGB_565; options.inJustDecodeBounds = false; return rotateBitmapByDegree(BitmapFactory.decodeFile(filePath, options), getBitmapDegree(filePath)); } else { return null; } } /** * 採樣率(等比)壓縮 * * @param uri 圖片uri * @param context * @return */ public static Bitmap getCompressBitmapFromUri(Context context, Uri uri, int reqHeight, int reqWidth) { return getCompressBitmap(getPathByUri(context, uri), reqHeight, reqWidth); } /** * 質量壓縮並存儲 * * @param bitmap * @param outFilePath 輸出路徑 * @param outSize 壓縮後輸出大小 kb */ public static void compressAndSaveImage(final Bitmap bitmap, final String outFilePath, final int outSize) { if (bitmap == null){ return; } new Thread(new Runnable() { @Override public void run() { ByteArrayOutputStream baos = new ByteArrayOutputStream(); int options = 100; //質量壓縮方法,把壓縮後的數據存放到baos中 (100表示不壓縮,0表示壓縮到最小) bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos); // 循環判斷如果壓縮後圖片是否大於100kb,大於繼續壓縮 while (baos.toByteArray().length / 1024 > outSize) { // 重置baos即讓下一次的寫入覆蓋之前的內容 baos.reset(); options -= 10; if (options < 0) { options = 0; } bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos); if (options == 0) { break; } } try { FileOutputStream fos = new FileOutputStream(new File(outFilePath)); fos.write(baos.toByteArray()); fos.flush(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }).start(); } /** * 質量壓縮並存儲 * * @param bitmap * @param outFilePath 輸出路徑 */ public static void saveImage(final Bitmap bitmap, final String outFilePath) { if (bitmap == null){ return; } new Thread(new Runnable() { @Override public void run() { try { int options = 100; FileOutputStream fos = new FileOutputStream(new File(outFilePath)); bitmap.compress(Bitmap.CompressFormat.JPEG, options, fos); fos.flush(); fos.close(); } catch (Exception e) { e.printStackTrace(); } } }).start(); } /** * 計算圖片縮放值 * * @param options * @param reqWidth * @param reqHeight * @return */ public static int caculateInSampleSize(BitmapFactory.Options options, int reqHeight, int reqWidth) { final int width = options.outWidth; final int height = options.outHeight; int inSampleSize = 1; if (width > reqWidth || height > reqHeight) { final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } public static String getPathByUri(Context context, Uri uri) { if ("content".equalsIgnoreCase(uri.getScheme())) { return getDataColumn(context, uri); } else { File file = new File(uri.getPath()); if (file.exists()) { return uri.getPath(); } } return null; } /** * uri路徑查詢字段 * * @param context * @param uri * @return */ public static String getDataColumn(Context context, Uri uri) { Cursor cursor = null; final String column = "_data"; final String[] projection = {column}; try { cursor = context.getContentResolver().query(uri, projection, null, null, null); if (cursor != null && cursor.moveToFirst()) { final int index = cursor.getColumnIndexOrThrow(column); return cursor.getString(index); } } finally { if (cursor != null) cursor.close(); } return null; } /** * 讀取圖片的旋轉的角度 * * @param path 圖片絕對路徑 * @return 圖片的旋轉角度 */ public static int getBitmapDegree(String path) { int degree = 0; try { // 從指定路徑下讀取圖片,並獲取其EXIF信息 ExifInterface exifInterface = new ExifInterface(path); // 獲取圖片的旋轉信息 int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); 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; } } catch (IOException e) { e.printStackTrace(); } return degree; } public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) { Bitmap returnBm = null; try { // 將原始圖片按照旋轉矩陣進行旋轉,並得到新的圖片 if (bm != null) { // 根據旋轉角度,生成旋轉矩陣 Matrix matrix = new Matrix(); matrix.postRotate(degree); returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); } } catch (OutOfMemoryError e) { } if (returnBm == null) { returnBm = bm; } if (bm != returnBm) { bm.recycle(); } return returnBm; }
獲得相冊或者拍照後數據處理方法:
//REQ_WIDTH和REQ_HEIGHT 是期望得到照片的大小
if (data.getData() == null) return; if (data.getData().getPath().startsWith("file")) { toastMsg(getResourceString(R.string.please_select_native_pic)); return; } Bitmap bm = getCompressBitmapFromUri(this, data.getData(), REQ_WIDTH, REQ_HEIGHT);