Android 呼叫系統相機相簿並獲取路徑並進行圖片壓縮
阿新 • • 發佈:2019-02-15
我直接從專案copy過來了專案程式碼段落,有些可以直接不要,我會加註釋的
1.先定義一個相機或者相簿的標識碼
private int REQUEST_CODE_PICK = 101;
private int REQUEST_CODE_CAMERA = 102;
2.然後我們就要跳轉了,因為我是Dialog彈窗所以這邊會有個postion判斷點選的是否相機或者相簿
if (position == 0) {//開啟相簿 Intent intent = new Intent(); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/*"); if (Build.VERSION.SDK_INT < 19) { intent.setAction(Intent.ACTION_GET_CONTENT); } else { intent.setAction(Intent.ACTION_OPEN_DOCUMENT); } startActivityForResult(intent, REQUEST_CODE_PICK); } else if (position == 1) {//開啟相機 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //下面這句指定呼叫相機拍照後的照片儲存的路徑 intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri .fromFile(new File(Environment.getExternalStorageDirectory().getPath()+"/"+"table.jpg"))); startActivityForResult(intent, REQUEST_CODE_CAMERA); }
3.下面我們要寫一下相機或者相簿的回撥
//相機相簿的回撥 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_PICK && resultCode == RESULT_OK) { String path = GetPathFromUri.getPath(UploadSkillCertifyActivity.this, data.getData()); //imgPath就是壓縮後的圖片 String imgPath = BitmapUtil.compressImageUpload(path); } else if (requestCode == REQUEST_CODE_CAMERA && resultCode == RESULT_OK) { String cameraPath = Environment .getExternalStorageDirectory().getPath()+"/"+"table.jpg"; //imgPath就是壓縮後的圖片 String imgPath = BitmapUtil.compressImageUpload(path); } }
4.寫一下GetPathFromUri的獲取路徑工具類
public class GetPathFromUri { @SuppressLint("NewApi") public static String getPath(final Context context, final Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; // DocumentProvider if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { // ExternalStorageProvider if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } // TODO handle non-primary volumes } // DownloadsProvider else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } // MediaProvider else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[]{split[1]}; return getDataColumn(context, contentUri, selection, selectionArgs); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(uri.getScheme())) { return getDataColumn(context, uri, null, null); } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; } /** * Get the value of the data column for this Uri. This is useful for * MediaStore Uris, and other file-based ContentProviders. * * @param context The context. * @param uri The Uri to query. * @param selection (Optional) Filter used in the query. * @param selectionArgs (Optional) Selection arguments used in the query. * @return The value of the _data column, which is typically a file path. */ public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; final String column = "_data"; final String[] projection = {column}; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int column_index = cursor.getColumnIndexOrThrow(column); return cursor.getString(column_index); } } finally { if (cursor != null) cursor.close(); } return null; } /** * @param uri The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. */ public static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is DownloadsProvider. */ public static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is MediaProvider. */ public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } }
5.再寫一下BitmapUtil對圖片的壓縮工具類
public class BitmapUtil {
/**
* 質量壓縮方法
*
* @param image
* @return
*/
private static Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
int options = 100;
while (baos.toByteArray().length / 1024 > 100) {
baos.reset();
image.compress(Bitmap.CompressFormat.JPEG, options, baos);
options -= 10;
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
return bitmap;
}
/**
* 圖片按比例大小壓縮方法(根據路徑獲取圖片並壓縮)
*
* @param srcPath
* @return
*/
private static Bitmap getImage(String srcPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此時返回bm為空
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
// 現在主流手機比較多是800*480解析度,所以高和寬我們設定為
float hh = 800f;// 這裡設定高度為800f
float ww = 480f;// 這裡設定寬度為480f
// 縮放比。由於是固定比例縮放,只用高或者寬其中一個數據進行計算即可
int be = 1;// be=1表示不縮放
if (w > h && w > ww) {// 如果寬度大的話根據寬度固定大小縮放
be = (int) (newOpts.outWidth / ww);
} else if (w < h && h > hh) {// 如果高度高的話根據寬度固定大小縮放
be = (int) (newOpts.outHeight / hh);
}
if (be <= 0)
be = 1;
newOpts.inSampleSize = be;// 設定縮放比例
// 重新讀入圖片,注意此時已經把options.inJustDecodeBounds 設回false了
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
return compressImage(bitmap);// 壓縮好比例大小後再進行質量壓縮
}
/**
* 將壓縮的bitmap儲存到SDCard卡臨時資料夾,用於上傳
*
* @param filename
* @param bit
* @return
*/
private static String saveMyBitmap(String filename, Bitmap bit) {
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath()+"/laopai/";
String filePath = baseDir + filename;
File dir = new File(baseDir);
if (!dir.exists()) {
dir.mkdir();
}
File f = new File(filePath);
try {
f.createNewFile();
FileOutputStream fOut = null;
fOut = new FileOutputStream(f);
bit.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return filePath;
}
/**
* 壓縮上傳路徑
* @param path
* @return
*/
public static String compressImageUpload(String path) {
String filename = path.substring(path.lastIndexOf("/") + 1);
Bitmap image = getImage(path);
return saveMyBitmap(filename, image);
}
/**
* 清除快取檔案
*/
public static void deleteCacheFile(){
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/laopai/");
RecursionDeleteFile(file);
}
/**
* 遞迴刪除
*/
private static void RecursionDeleteFile(File file){
if(file.isFile()){
file.delete();
return;
}
if(file.isDirectory()){
File[] childFile = file.listFiles();
if(childFile == null || childFile.length == 0){
file.delete();
return;
}
for(File f : childFile){
RecursionDeleteFile(f);
}
file.delete();
}
}
}
6.好了到這裡就完成了,有什麼不懂的可以問我