我想写一个模块,在点击一个按钮,相机打开,我可以点击和捕捉图像。如果我不喜欢图像,我可以删除它,然后点击另一个图像,然后选择图像,它应该返回并在活动中显示该图像。
当前回答
正如其他人所讨论的,使用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等成员的枚举)
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 如何在TextView中添加一个子弹符号?
- PreferenceManager getDefaultSharedPreferences在Android Q中已弃用
- 在Android Studio中创建aar文件