安卓6.0以上從相簿選擇圖片,圖片壓縮及動態許可權

KyLin_FY發表於2018-04-06

這幾天自己做一個圖片載入,並優化圖片,由於是小白,走了很多坑,這裡記錄一下,提醒自己,也讓大家參考,避免走坑。

本文包含多個要素(圖片優化處理,呼叫系統相簿,壓縮圖片,動態許可權獲取等)

首先是從相簿獲取圖片

//呼叫系統相簿
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");// 相片型別
startActivityForResult(intent, 1);

然後在onActivityResult()方法中處理圖片

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 1) {
        
Uri uri = data.getData();//獲取圖片uri
  String imagePath = UriToPath.getRealFilePath(getApplicationContext(), uri);//將uri轉換為path
  System.out.println(imagePath);
  et_add_content.measure(0, 0);
  int width = ScreenUtils.getScreenWidth(AddNoteActivity.this);
  int height = ScreenUtils.getScreenHeight(AddNoteActivity.this);
  Bitmap bitmap = ImageUtils.getSmallBitmap(imagePath, width, height);//壓縮圖片;
  imagePath = SDCardUtil.saveToSdCard(bitmap);//儲存圖片
}}

imagePath為儲存後的圖片路徑,具體幹什麼大家可自行處理

Uri轉path路徑方法

/**
 * Uri轉換為路徑
 *
 * @param context
 * @param uri
 * @return the file path or null
 */
public static String getRealFilePath(final Context context, final Uri uri ) {
    if ( null == uri ) return null;
    final String scheme = uri.getScheme();
    String data = null;
    if ( scheme == null )
        data = uri.getPath();
    else if ( ContentResolver.SCHEME_FILE.equals( scheme ) ) {
        data = uri.getPath();
    } else if ( ContentResolver.SCHEME_CONTENT.equals( scheme ) ) {
        Cursor cursor = context.getContentResolver().query( uri, new String[] { MediaStore.Images.ImageColumns.DATA }, null, null, null );
        if ( null != cursor ) {
            if ( cursor.moveToFirst() ) {
                int index = cursor.getColumnIndex( MediaStore.Images.ImageColumns.DATA );
                if ( index > -1 ) {
                    data = cursor.getString( index );
                }
            }
            cursor.close();
        }
    }
    return data;
}

壓縮圖片方法:

/**
 * 根據路徑獲得圖片並壓縮返回bitmap用於顯示
 *
 * @return
 */
public static Bitmap getSmallBitmap(String filePath, int newWidth, int newHeight) {
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(filePath, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, newWidth, newHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;

    Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
    Bitmap newBitmap = compressImage(bitmap, 500);
    if (bitmap != null){
        bitmap.recycle();
    }
    return newBitmap;
}

/**
 * 計算圖片的縮放值
 *
 * @param options
 * @param reqWidth
 * @param reqHeight
 * @return
 */
public static int calculateInSampleSize(BitmapFactory.Options options,
                                        int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        // Calculate ratios of height and width to requested height and
        // width
        final int heightRatio = Math.round((float) height / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        // Choose the smallest ratio as inSampleSize value, this will
        // guarantee
        // a final image with both dimensions larger than or equal to the
        // requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }

    return inSampleSize;
}

SD卡儲存圖片:

/**
 * 圖片儲存到SD * @param bitmap
 * @return
 */
public static String saveToSdCard(Bitmap bitmap) {
   String imageUrl = getPictureDir() + System.currentTimeMillis() + "-";
   File file = new File(imageUrl);
   try {
      FileOutputStream out = new FileOutputStream(file);
      if (bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out)) {
         out.flush();
         out.close();
      }
   } catch (FileNotFoundException e) {
      e.printStackTrace();
   } catch (IOException e) {
      e.printStackTrace();
   }
   return file.getAbsolutePath();
}

在對圖片處理時,剛開始老是獲取不到圖片,找了各種方法,一直沒有解決(編譯版本是sdk25)

後來發現6.0以後讀取sd卡圖片需要動態新增許可權(真的坑啊)

//動態許可權的申請
private static final String[] PERMISSION_EXTERNAL_STORAGE = new String[]{
        Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE};
private static final int REQUEST_EXTERNAL_STORAGE = 100;


/**
 * 動態許可權的申請
 *
 */
private void verifyStoragePermissions() {
    int permissionWrite = ActivityCompat.checkSelfPermission(this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (permissionWrite != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, PERMISSION_EXTERNAL_STORAGE,
                REQUEST_EXTERNAL_STORAGE);
    }
}


相關文章