Android Q:从图库中获取图像并进行处理 [英] Android Q: Get image from gallery and process it

查看:436
本文介绍了Android Q:从图库中获取图像并进行处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这似乎是一个非常基本的问题,但这是专门针对Android Q的.

I know it seems like a very basic question, but it's specifically for Android Q.

我只想从Gallery获取图像并将其压缩并发送到服务器.但是由于Android Q的范围存储,它比我想象的要难.我将首先解释我对代码的处理方式:

I just want to get an image from Gallery and compress it and send to the server. But because of the Android Q's Scoped Storage, it's harder than I thought. I'll first explain what I did with code:

首先,我发出选择图像的意图.

First I send out the intent to pick the image.

fun openGallery(fragment: Fragment){
    val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
    intent.type = "*/*"
    val mimeTypes = arrayOf("image/*")
    intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
    fragment.startActivityForResult(intent, REQUEST_IMAGE_PICK)
}

它工作正常,我可以通过onActivityResult方法获取图片

It works fine, and I'm able to get the image in the onActivityResult method

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

    if (requestCode == REQUEST_IMAGE_PICK && resultCode == Activity.RESULT_OK && null != data) {
        val selectedImage = data.data

        val source = ImageDecoder.createSource(activity!!.contentResolver, selectedImage)
        val bitmap = ImageDecoder.decodeBitmap(source)
        mBinding.circularProfileImage.setImageBitmap(bitmap)
    }
}

现在好,问题是如何以文件格式访问此图像,以便进一步处理/压缩它.

Okay now the question is how can I access this image in File format, so I can further process/compress it.

以下是我尝试过的事情:

Following things I've tried:

val mImagePath = getImagePathFromUri(activity!!, selectedImage)

这是我要走的路:

/storage/emulated/0/DCIM/Camera/IMG_20191022_152437.jpg

我通过以下方式从其中创建了一个文件:

I created a file from it, in the following way:

val file = File(mImagePath)

以下是我自定义的压缩和上传图像的逻辑:

And Following is my custom logic to compress and upload image:

val mNewFile = MediaCompressor.compressCapturedImage(activity!!, file, "ProfilePictures")
uploadProfile(mNewFile)

在这种自定义逻辑中,我有一种方法来处理图像的采样和旋转,如下所示:

In this custom logic, I have a method to handle sampling and rotation of the image as follows:

fun handleSamplingAndRotationBitmap(context: Context, selectedImage: File, reqWidth: Int, reqHeight: Int): Bitmap {

    val mUri = Uri.fromFile(selectedImage)

    // First decode with inJustDecodeBounds=true to check dimensions
    val options = BitmapFactory.Options()
    options.inJustDecodeBounds = true
    var imageStream = context.contentResolver.openInputStream(mUri)
    BitmapFactory.decodeStream(imageStream, null, options)
    imageStream!!.close()

    // Calculate inSampleSize
    options.inSampleSize =
        calculateInSampleSize(options, reqWidth, reqHeight)

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false
    imageStream = context.contentResolver.openInputStream(mUri)

    var img = BitmapFactory.decodeStream(imageStream, null, options)

    img = rotateImageIfRequired(context, img!!, mUri)
    return img
}

但是当我尝试使用 context.contentResolver.openInputStream 打开流时 我收到以下错误:

But when I'm trying to open the stream using context.contentResolver.openInputStream I get the following error:

java.io.FileNotFoundException: /storage/emulated/0/DCIM/Camera/IMG_20191022_152437.jpg: open failed: EACCES (Permission denied)

我知道我要这么做了,因为在Android 10中,我们无权直接访问外部存储中的文件.

I know I'm getting this because in Android 10 we don't have the permission to directly access files from external storage.

因此,请帮我弄清楚,如何将外部存储中的图像用作Android 10中的文件.

So, please help me figure this out, how can I use the image from external storage as a file in Android 10.

注意:我拥有所有必需的权限,所以这不是问题

Note: I've all the required permissions, so that's not the issue

推荐答案

以下是我尝试过的事情:

Following things I've tried:

没有可靠的getImagePathFromUri()实施方式.

在这种自定义逻辑中,我有一种方法来处理图像的采样和旋转,如下所示:

In this custom logic, I have a method to handle sampling and rotation of the image as follows:

该功能中不需要File.毕竟,您在该函数中的第一个语句会从该File创建一个Uri.因此,将File参数替换为您拥有的Uri,然后跳过Uri.fromFile()调用.

You do not need a File in that function. After all, your very first statement in that function goes and creates a Uri from that File. So, replace the File parameter with the Uri that you have, and skip the Uri.fromFile() call.

如何将外部存储中的图像用作Android 10中的文件.

how can I use the image from external storage as a file in Android 10.

不能.而且,如上所述,您不需要在做任何事情.

You can't. And, as demonstrated above, you do not need it for what you are doing.

如果您发现自己陷入了某种困境,那就是使用某些肯定是必须具有File的库或API:

If you find yourself in some situation where you are stuck using some library or API that absolutely positively must have a File:

  • 像今天一样使用contentResolver.openInputStream()在内容上打开InputStream
  • 将字节InputStream中的字节复制到您可以读取/写入的文件中的某些FileOutputStream中(例如Context上的getCacheDir())
  • 将副本与需要File
  • 的库或API一起使用
  • Open an InputStream on the content, using contentResolver.openInputStream(), as you are doing today
  • Copy the bytes from that InputStream to some FileOutputStream on a file that you can read/write (e.g., getCacheDir() on Context)
  • Use your copy with the library or API that requires a File

这篇关于Android Q:从图库中获取图像并进行处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆