android呼叫相機拍照返回的照片大小太小,變得模糊
阿新 • • 發佈:2018-11-04
1、使用相機拍照預設情況下呼叫相機的方式:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAMERA_REQUEST_CODE);//CAMERA_REQUEST_CODE=1一個int表示請求碼
在onActivityResult中獲取返回的圖片:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Log.i("test=suc", "onActivityResult"); if (requestCode == CAMERA_REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) { Bundle bundle = data.getExtras(); if (bundle != null) { Bitmap bitmap = (Bitmap) bundle.get("data"); if (bitmap != null) { mImageView.setImageBitmap(bitmap); //儲存Bitmap圖片到相簿,檔案的儲存函式我就不寫了 } } } }
你會發現無論是mImageView顯示出來的圖片,還是自己儲存到指定資料夾的圖片都橫小。那是因為這種方式預設壓縮了圖片,畫素大概188*256大小。
於是我們換一個思路,預設是先從data中獲取bitmap(被壓縮了),再儲存bitmap到本地。我們改為改為先儲存到本地(沒有壓縮),然後從本地讀取圖片顯示,就能顯示大圖了。
從兩種方法的比較看,可以找到被壓縮的原因,如果直接返回bitmap,圖片太大會影響程式效率,預設就壓縮了。如果儲存到本地,本地有足夠儲存空間,系統就沒壓縮圖片。
2、呼叫相機時候指定儲存地址:
private void takePhoto() { //獲取許可權 getPermission(); //獲取儲存位置 createFile(); mImageName = "" + System.currentTimeMillis() + ".jpg"; Intent it = new Intent("android.media.action.IMAGE_CAPTURE"); it.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(mImagePath + mImageName))); startActivityForResult(it, REQUEST_TAKEPHOTO_CODE2); }
其中getPermission(); 是為了動態獲取相機許可權,android6.0以上需要動態獲取,函式程式碼繼續往下看,
createFile();是為了為儲存的圖片指定儲存位置,函式程式碼在後面,
mImagePath, mImageName, 分別表示檔案路徑和名字,為String型別的全域性變數
REQUEST_TAKEPHOTO_CODE2, 是一個int型別的請求標識。
函式程式碼如下:com.zhengyuan.learningtakephoto是自己專案的包名
private void getPermission() { PackageManager pm = getPackageManager(); boolean permission = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.CAMERA", "com.zhengyuan.learningtakephoto")); if (!permission) { //沒有許可權 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(new String[]{Manifest.permission.CAMERA}, 15); } } permission = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.READ_EXTERNAL_STORAGE", "com.zhengyuan.learningtakephoto")); if (!permission) { //沒有許可權 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 15); } } permission = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.WRITE_EXTERNAL_STORAGE", "com.zhengyuan.learningtakephoto")); if (!permission) { //沒有許可權 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 15); } } } /** * 建立儲存圖片的資料夾 */ public void createFile() { mImagePath = Environment.getExternalStorageDirectory() + "/mypp/";//指定儲存路徑 File f = new File(mImagePath); if (!f.exists()) { f.mkdir(); } }
拍照完成後再onActivityResult顯示儲存到本地的圖片:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
else if (requestCode == REQUEST_TAKEPHOTO_CODE2&& data != null) {
try {
Bitmap bm = BitmapFactory.decodeFile(mImagePath + mImageName);
Bitmap take = ResizeBitmap(bm, 640);
mImageView2.setImageBitmap(take);
bm.recycle();//太大記得回收
//處理完記得回收take
//take.recycle();
} catch (Exception e) {
}
}
}
上面變數中有兩個bitmap,bm是直接從本地讀取的,太大,為了適應手機顯示,壓縮成take顯示。壓縮函式如下:
public static Bitmap ResizeBitmap(Bitmap bitmap, int newWidth) {//拍照的圖片太大,設定格式大小
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float temp = ((float) height) / ((float) width);
int newHeight = (int) ((newWidth) * temp);
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// matrix.postRotate(45);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
bitmap.recycle();
return resizedBitmap;
}