Android开发:关于调用摄像头拍照时返回图像模糊的解决方法

最近在实现调用摄像头拍照, 使返回的图像显示在主界面, 然后进行目标检测的功能. 但是在实现过程中, 我发现返回的图像总是很模糊, 根本没办法进行目标检测. 于是我在网上寻找答案, 最后发现原来直接使用以下代码, 在onActivityResult()用bitmap = (Bitmap) data.getExtras().get("data")接收的data是一个缩略图.

Intent takePicture = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePicture, TAKE_PHOTO);

解决方法就是, 在拍照时直接将图片保存下来, 然后在onActivityResult()中直接调用相册里的图片就可以了. 

在按钮监听中的代码如下, 其中需要判断手机是否是android7.0以上的手机(现在应该都是了吧), 如果是7.0以上需要调用takePhotoBiggerThan7方法. 其中需要传入保存照片的路径.

// 拍照
        takephoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 获取SD卡路径
                mFilePath = Environment.getExternalStorageDirectory().getPath();
                // 保存图片的文件名
                mFilePath = mFilePath + "/" + "image.jpg";

                if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
                    // 如果手机是android7.0以上的手机
                    takePhotoBiggerThan7((new File(mFilePath)).getAbsolutePath());
                }else {
                    Intent takePicture1 = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                    // 加载路径图片路径
                    Uri mUri = Uri.fromFile(new File(mFilePath));
                    // 指定存储路径,这样就可以保存原图了
                    takePicture1.putExtra(MediaStore.EXTRA_OUTPUT, mUri);

                    startActivityForResult(takePicture1, TAKE_PHOTO);
                }

            }
        });

takePhotoBiggerThan7()方法的代码为: 

private void takePhotoBiggerThan7(String absolutePath) {
        try {
            // ContentValues类用来储存ContentResolver可以处理的一些值
            ContentValues values = new ContentValues(1);
            // first parameter is the name of the value
            // the second parameter represents the value
            values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpg");
            values.put(MediaStore.Images.Media.DATA, absolutePath);
            // getContentResolver()用来返回一个ContentResolver实例
            // insert() return a new URL, the first parameter is the URL of the table to insert into.
            // the second parameter is the initial values for the newly inserted row
            mCameraTempUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            // addFlags is used chains multiple calls
            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_PHOTO);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

还有一个需要注意的地方, 如果我们使用intent.putExtra(MediaStore.EXTRA_OUTPUT, mCameraTempUri);方法向intent中放入保存文件的Uri, 那么onActivityResult()中返回的data就为null, 如果不用Uri,data返回的就是图像的缩略图. 

如果传入了保存路径的Uri, 那么我们要想得到拍摄的原图就需要用以下方法得到拍摄的bitmap. 然后再通过各自的需求来处理bitmap就好了. 

bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(mCameraTempUri));

猜你喜欢

转载自blog.csdn.net/Orange_sparkle/article/details/129170679