我想写一个模块,在点击一个按钮,相机打开,我可以点击和捕捉图像。如果我不喜欢图像,我可以删除它,然后点击另一个图像,然后选择图像,它应该返回并在活动中显示该图像。


当前回答

正如其他人所讨论的,使用data. getextras ().get("data")只会得到低质量的缩略图。

解决方案是通过ACTION_IMAGE_CAPTURE意图传递一个位置,告诉相机在哪里存储全质量图像。

代码是Kotlin,不需要任何权限。


val f = File("${getExternalFilesDir(null)}/imgShot")
val photoURI = FileProvider.getUriForFile(this, "${packageName}.fileprovider", f)
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        .apply { putExtra(MediaStore.EXTRA_OUTPUT, photoURI) }
startActivityForResult(intent, 1234)

然后对拍摄后的结果进行处理:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (requestCode == 1234 && resultCode == Activity.RESULT_OK) {
        val bitmap = BitmapFactory.decodeFile(
                File("${getExternalFilesDir(null)}/imgShot").toString()
        )
        // use imageView.setImageBitmap(bitmap) or whatever
    }
}

您还需要像这里描述的那样添加一个外部FileProvider。AndroidManifest.xml:

<manifest>
    <application>

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provide_paths" />
        </provider>

    </application>
</manifest>

添加一个新文件app/src/main/res/xml/provide_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="external_files" path="." />
</paths>

最后,你应该用你自己的逻辑替换1234来跟踪请求代码(通常是一个包含RequestCode.CAPTURE_IMAGE等成员的枚举)

其他回答

请使用Kotlin和Andoirdx支持来实现这个例子:

button1.setOnClickListener{
        file = getPhotoFile()
        val uri: Uri = FileProvider.getUriForFile(applicationContext, "com.example.foto_2.filrprovider", file!!)
        captureImage.putExtra(MediaStore.EXTRA_OUTPUT, uri)

        val camaraActivities: List<ResolveInfo> = applicationContext.getPackageManager().queryIntentActivities(captureImage, PackageManager.MATCH_DEFAULT_ONLY)

        for (activity in camaraActivities) {
            applicationContext.grantUriPermission(activity.activityInfo.packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
        }

        startActivityForResult(captureImage, REQUEST_PHOTO)
    }

活动结果:

if (requestCode == REQUEST_PHOTO) {
        val uri = FileProvider.getUriForFile(applicationContext, "com.example.foto_2.filrprovider", file!!)
        applicationContext.revokeUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
        imageView1.viewTreeObserver.addOnGlobalLayoutListener {
            width = imageView1.width
            height = imageView1.height
            imageView1.setImageBitmap(getScaleBitmap(file!!.path , width , height))
        }
        if(width!=0&&height!=0){
            imageView1.setImageBitmap(getScaleBitmap(file!!.path , width , height))
        }else{
            val size = Point()
            this.windowManager.defaultDisplay.getSize(size)
            imageView1.setImageBitmap(getScaleBitmap(file!!.path , size.x , size.y))
        }

    }

您可以在https://github.com/joelmmx/take_photo_kotlin.git上获得更多详细信息

我希望它能帮助你!

你得好好研究一下相机。(我认为要做到你想要的,你必须保存当前的图像到你的应用程序,在那里做选择/删除,然后召回相机再试一次,而不是直接在相机内部重试。)

您可以使用自定义相机与缩略图图像。 你可以看看我的项目。

坏的质量

根据我的经验,如果我们使用

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, RESULT_ADD_PHOTO);

和处理onActivityResult()

Bitmap thumbnail= (Bitmap) data.getExtras().get("data");

它只会给你一个缩略图,当然有一个坏的质量。

不错的质量

您可以显示相机和保存您的图像文件在公共目录,例如在文档目录

在onClick()中使用这个

String imagePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) +
                File.separator + "your_image_name.jpeg";
Intent i =new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
imageFile = new File(imagePath );
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile));
startActivityForResult(i, RESULT_ADD_PHOTO);

在onActivityResult()中

Bitmap imageBitmap1 = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap imageBitmap = Bitmap.createBitmap(imageBitmap1, 0, 0, imageBitmap1.getWidth(), imageBitmap1.getHeight(), matrix, true);
binding.imageView.setImageBitmap(imageBitmap);

我使用postRotate(),因为在我的代码中,图像结果向左旋转,所以我需要将其旋转90

正如其他人所讨论的,使用data. getextras ().get("data")只会得到低质量的缩略图。

解决方案是通过ACTION_IMAGE_CAPTURE意图传递一个位置,告诉相机在哪里存储全质量图像。

代码是Kotlin,不需要任何权限。


val f = File("${getExternalFilesDir(null)}/imgShot")
val photoURI = FileProvider.getUriForFile(this, "${packageName}.fileprovider", f)
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        .apply { putExtra(MediaStore.EXTRA_OUTPUT, photoURI) }
startActivityForResult(intent, 1234)

然后对拍摄后的结果进行处理:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (requestCode == 1234 && resultCode == Activity.RESULT_OK) {
        val bitmap = BitmapFactory.decodeFile(
                File("${getExternalFilesDir(null)}/imgShot").toString()
        )
        // use imageView.setImageBitmap(bitmap) or whatever
    }
}

您还需要像这里描述的那样添加一个外部FileProvider。AndroidManifest.xml:

<manifest>
    <application>

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provide_paths" />
        </provider>

    </application>
</manifest>

添加一个新文件app/src/main/res/xml/provide_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="external_files" path="." />
</paths>

最后,你应该用你自己的逻辑替换1234来跟踪请求代码(通常是一个包含RequestCode.CAPTURE_IMAGE等成员的枚举)