使用相机意图在Android中获取捕获图像的路径

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20327213/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 02:40:54  来源:igfitidea点击:

Getting path of captured image in Android using camera intent

androidandroid-camera-intent

提问by Shubham

I have been trying to get path of captured image in order to delete image. Found many answers on StackOverflow but none of them are working for me. I got the following answer:

我一直在尝试获取捕获图像的路径以删除图像。在 StackOverflow 上找到了很多答案,但没有一个对我有用。我得到了以下答案:

private String getLastImagePath() {
    final String[] imageColumns = { MediaStore.Images.Media._ID,
            MediaStore.Images.Media.DATA };
    final String imageOrderBy = MediaStore.Images.Media._ID + " DESC";
    Cursor imageCursor = POS.this.getContentResolver().query(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns,
            null, null, imageOrderBy);
    if (imageCursor.moveToFirst()) {
        // int id = imageCursor.getInt(imageCursor
        // .getColumnIndex(MediaStore.Images.Media._ID));
        String fullPath = imageCursor.getString(imageCursor
                .getColumnIndex(MediaStore.Images.Media.DATA));
        return fullPath;
    } else {
        return "";
    }
}

This code works in Samsung tab but doesn't work in Lenovo tab and i-ball tab. So, can anyone help me find another solution to do the same? Any help will be appreciated. Thank you.

此代码适用于 Samsung 选项卡,但不适用于 Lenovo 选项卡和 i-ball 选项卡。那么,谁能帮我找到另一个解决方案来做同样的事情?任何帮助将不胜感激。谢谢你。

This is my onActivityResult:

这是我的 onActivityResult:

if (requestCode == CmsInter.CAMERA_REQUEST && resultCode == RESULT_OK) {
    //Bitmap photo = null;
    //photo = (Bitmap) data.getExtras().get("data");

    String txt = "";
    if (im != null) {
        String result = "";
        //im.setImageBitmap(photo);
        im.setTag("2");
        int index = im.getId();
        String path = getLastImagePath();
        try {
            bitmap1 = BitmapFactory.decodeFile(path, options);
            bitmap = Bitmap.createScaledBitmap(bitmap1, 512, 400, false);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
            byte[] bytData = baos.toByteArray();
            try {
                baos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            result = Base64.encode(bytData);
            bytData = null;
        } catch (OutOfMemoryError ooM) {
            System.out.println("OutOfMemory Exception----->" + ooM);
            bitmap1.recycle();
            bitmap.recycle();
        } finally {
            bitmap1.recycle();
            bitmap.recycle();
        }
    }
}

回答by Aamirkhan

Try like this

像这样尝试

Pass Camera Intent like below

通过像下面这样的相机意图

Intent intent = new Intent(this);
startActivityForResult(intent, REQ_CAMERA_IMAGE);

And after capturing image Write an OnActivityResultas below

并在捕获图像后写一个OnActivityResult如下

protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
    if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
        Bitmap photo = (Bitmap) data.getExtras().get("data"); 
        imageView.setImageBitmap(photo);
        knop.setVisibility(Button.VISIBLE);


        // CALL THIS METHOD TO GET THE URI FROM THE BITMAP
        Uri tempUri = getImageUri(getApplicationContext(), photo);

        // CALL THIS METHOD TO GET THE ACTUAL PATH
        File finalFile = new File(getRealPathFromURI(tempUri));

        System.out.println(mImageCaptureUri);
    }  
}

public Uri getImageUri(Context inContext, Bitmap inImage) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
    String path = Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
    return Uri.parse(path);
}

public String getRealPathFromURI(Uri uri) {
    String path = "";
    if (getContentResolver() != null) {
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);
        if (cursor != null) {
            cursor.moveToFirst();
            int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            path = cursor.getString(idx);
            cursor.close();
        }
    }
    return path;
}

And check log

并检查日志

Edit:

编辑:

Lots of people are asking how to not get a thumbnail. You need to add this code instead for the getImageUrimethod:

很多人都在问如何不获取缩略图。您需要为该getImageUri方法添加以下代码:

public Uri getImageUri(Context inContext, Bitmap inImage) {
    Bitmap OutImage = Bitmap.createScaledBitmap(inImage, 1000, 1000,true);
    String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), OutImage, "Title", null);
    return Uri.parse(path);
}

The other method Compresses the file. You can adjust the size by changing the number 1000,1000

另一种方法压缩文件。您可以通过更改数字来调整大小1000,1000

回答by dzikovskyy

There is a solution to create file (on external cache dir or anywhere else) and put this file's uri as output extra to camera intent - this will define path where taken picture will be stored.

有一个解决方案可以创建文件(在外部缓存目录或其他任何地方)并将该文件的 uri 作为相机意图的额外输出 - 这将定义存储拍摄照片的路径。

Here is an example:

下面是一个例子:

File file;
Uri fileUri;
final int RC_TAKE_PHOTO = 1;

    private void takePhoto() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        file = new File(getActivity().getExternalCacheDir(), 
                String.valueOf(System.currentTimeMillis()) + ".jpg");
        fileUri = Uri.fromFile(file);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
        getActivity().startActivityForResult(intent, RC_TAKE_PHOTO);

    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == RC_TAKE_PHOTO && resultCode == RESULT_OK) {

                //do whatever you need with taken photo using file or fileUri

            }
        }
    }

Then if you don't need the file anymore, you can delete it using file.delete();

然后,如果您不再需要该文件,则可以使用 file.delete();

By the way, files from cache dir will be removed when user clears app's cache from apps settings.

顺便说一下,当用户从应用程序设置中清除应用程序的缓存时,缓存目录中的文件将被删除。

回答by Naveen Kumar M

Here I updated the sample code in Kotlin. Please note on Nougat and above version Uri.fromFile(file)is not working and it crashes the app for that need to implement FileProvider which is safest way to send files from intent. For implementing this refer this answeror this article

这里我更新了 Kotlin 中的示例代码。请注意牛轧糖及以上版本Uri.fromFile(file)无法正常工作,它会导致应用程序崩溃,因为需要实现 FileProvider,这是从意图发送文件的最安全方式。为了实现这个,请参考这个答案或这篇文章

private fun takePhotoFromCamera() {
        val isDeviceSupportCamera: Boolean = this.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)
        if (isDeviceSupportCamera) {
            val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)

            if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                file = File(getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS + "/attachments")!!.path,
                        System.currentTimeMillis().toString() + ".jpg")
//            fileUri = Uri.fromFile(file)
                fileUri = FileProvider.getUriForFile(this, this.applicationContext.packageName + ".provider", file!!)
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri)
                if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
                    takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
                }
                startActivityForResult(takePictureIntent, Constants.REQUEST_CODE_IMAGE_CAPTURE)
            }

        } else {
            Toast.makeText(this, this.getString(R.string.camera_not_supported), Toast.LENGTH_SHORT).show()
        }
    }

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_OK) {
             if(requestCode == Constants.REQUEST_CODE_IMAGE_CAPTURE) {
                realPath = file?.path
                 //do what ever you want to do
            }
    }
}

回答by Samir Elekberov

Please refer to Google Documentation: Camera - Photo Basics

请参阅 Google 文档: 相机 - 照片基础

回答by Bhargav Thanki

Try this method to get path of originalimage captured by camera.

尝试使用此方法获取original相机捕获的图像路径。

public String getOriginalImagePath() {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = getActivity().managedQuery(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                projection, null, null, null);
        int column_index_data = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToLast();

        return cursor.getString(column_index_data);
    }

This method will return path of the last image captured by camera. So this path would be of originalimage not of thumbnailbitmap.

此方法将返回相机捕获的最后一张图像的路径。所以这个路径将是原始图像而不是缩略图位图。

回答by Invader

try this

尝试这个

String[] projection = { MediaStore.Images.Media.DATA };
            @SuppressWarnings("deprecation")
            Cursor cursor = managedQuery(mCapturedImageURI, projection,
                    null, null, null);
            int column_index_data = cursor
                    .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            image_path = cursor.getString(column_index_data);
            Log.e("path of image from CAMERA......******************.........",
                    image_path + "");

for capturing image:

用于捕获图像:

    String fileName = "temp.jpg";
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.TITLE, fileName);
    mCapturedImageURI = getContentResolver().insert(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
    values.clear();