解决Android 调用相机拍照后得到的照片不清晰问题

最近在做一个需要上传拍照的APP,上传的时候因为是小图片,但是需求提了要点击可预览大图,一看大图,被吓到了,根本看不清楚,大图中的具体内容。原因是通过MediaStore.ACTION_IMAGE_CAPTURE方式直接去调用相机,在onactivityresult()方法中返回的结果data.getExtras().get(“data”)这种方式去获取的图片。当时大概测了一下,bitmap的大小在12K左右(我用的4.0的老手机测得,其他的不太清楚)。然而用相机拍摄的图片大小在手机相册中查看大约在2M左右,这完全不是一个级别。当然这个问题不是我首先发现的,是因为测试那边发现我穿的照片质量不清晰(尴尬的一笑)。
于是,我就去查了一下,原来调用系统相机去获取data时获取到的只是缩略图,如果想要查看大图,需要将拍照得到的原图则保存到手机中,然后再去读取。
下面我们就来看一下具体实现

  • 权限以及版本兼容问题
    调用相机权限肯定少不了,不仅仅要考虑到动态权限的请求,还要考虑到Android7.0以后对Uri一些操作,如果不做特别处理的话也会报异常(注意点)。我们先来做7.0版本之前的功能,直接上代码:
        // 获取SD卡路径
        mFilePath = Environment.getExternalStorageDirectory().getPath();
        // 保存图片的文件名
        mFilePath = mFilePath + "/" + "mytest.png";
        // 指定拍照意图
            Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            // 加载路径图片路径
            Uri mUri = Uri.fromFile(new File(mFilePath));
            // 指定存储路径,这样就可以保存原图了
            openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mUri);
            startActivityForResult(openCameraIntent, TAKE_PICTURE);

在onactivityresult()方法中做对应的处理:

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case TAKE_PICTURE:
                    try {
                        // 获取输入流
                        is = new FileInputStream(mFilePath);
                        // 把流解析成bitmap,此时就得到了清晰的原图
                        Bitmap bitmap = BitmapFactory.decodeStream(is);
                         //接下来就可以展示了(或者做上传处理)
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } finally {
                        // 关闭流
                        try {
                            is.close();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
    }

做到这里,图片的清晰度应该没问题了,但是如果你没有测试7.0以上的版本的话,那肯定不会发现下面的问题:

FATAL EXCEPTION: main android.os.FileUriExposedException: file:///storage/emulated/0/photo.png expos

这个问题怎么解决呢,所以我们在写调用拍照的代码的时候就要考虑到这个问题,因此只是对上面的第一块的代码进行一些更改就可以了,具体如下:

if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
            takePhotoBiggerThan7((new File(mFilePath)).getAbsolutePath());
        }else {
            // 指定拍照意图
            Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            // 加载路径图片路径
            Uri mUri = Uri.fromFile(new File(mFilePath));
            // 指定存储路径,这样就可以保存原图了
            openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mUri);
            startActivityForResult(openCameraIntent, TAKE_PICTURE);
        }
private void takePhotoBiggerThan7(String absolutePath) {
        Uri mCameraTempUri;
        try {
            ContentValues values = new ContentValues(1);
            values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpg");
            values.put(MediaStore.Images.Media.DATA, absolutePath);
            mCameraTempUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            if (mCameraTempUri != null) {
                intent.putExtra(MediaStore.EXTRA_OUTPUT, mCameraTempUri);
                intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
            }
            startActivityForResult(intent, TAKE_PICTURE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

到此,拍照得到的图片不清晰问题就OK了,这里就不上源码了,我想贴的已经够仔细了,如果有什么问题,大家可以指正,谢谢!

发布了37 篇原创文章 · 获赞 15 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/u012764358/article/details/79207685