1. 程式人生 > >android呼叫相機拍照返回的照片大小太小,變得模糊

android呼叫相機拍照返回的照片大小太小,變得模糊

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;
    }