Как отобразить изображение, снятое с помощью CameraX, в Android.
Мой случай: у меня есть два фрагмента. В одном из фрагментов я реализовал функционал CameraX, позволяющий сделать фотографию и сохранить ее локально. И теперь я хочу передать это изображение в другой фрагмент и отобразить его там в ImageView.
Каким должен быть лучший подход для этого (и можете ли вы предоставить рабочий код, который будет будьте полезны)
Подходы, которые я думаю для решения этой проблемы:
1-й подход: отправьте идентификатор Uri, который извлекается из переопределения onImageSaved (мы получаем идентификатор Uri в ImageCapture.OutputFileResults). Но с этим есть несколько проблем. При отправке Uri в виде пакета или безопасных аргументов с помощью навигации Android он отображается как нулевой. Это означает, что Uri не передается через навигацию.
2-й подход: преобразуйте Uri в растровое изображение, а затем отправьте это растровое изображение другому фрагмент. Там декодируйте растровое изображение, чтобы поместить его в ImageView. Я не уверен в этом подходе. Если вы уже работали с этим раньше, дайте мне знать.
Есть ли другие способы решения этой проблемы. Я не могу найти ни одной статьи по этой теме в официальной документации Android.
Фрагмент камеры (1-й фрагмент):
class CameraFragment : Fragment() {
private var _binding: FragmentCameraBinding? = null
private val binding: FragmentCameraBinding get() = _binding!!
private var imageCapture: ImageCapture? = null
private lateinit var cameraExecutor: ExecutorService
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
_binding = FragmentCameraBinding.inflate(inflater, container, false)
//Request Camera Permissions
// Request camera permissions
if (allPermissionsGranted()) {
startCamera()
} else {
ActivityCompat.requestPermissions(
requireActivity(), REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS
)
}
cameraExecutor = Executors.newSingleThreadExecutor()
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//Setting up listeners for taking Photo
binding.imageCaptureButton.setOnClickListener {
takePhoto()
}
}
private fun takePhoto() {
// Get a stable reference of the modifiable image capture use case
val imageCapture = imageCapture ?: return
// Create time stamped name and MediaStore entry.
val name = SimpleDateFormat(FILENAME_FORMAT, Locale.US)
.format(System.currentTimeMillis())
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, name)
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/CameraX-Image")
}
}
// Create output options object which contains file + metadata
val outputOptions = ImageCapture.OutputFileOptions
.Builder(
requireContext().contentResolver,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
contentValues
)
.build()
// Set up image capture listener, which is triggered after photo has
// been taken
imageCapture.takePicture(
outputOptions,
ContextCompat.getMainExecutor(requireContext()),
object : ImageCapture.OnImageSavedCallback {
override fun onError(exc: ImageCaptureException) {
Timber.e("Photo capture failed: ${exc.message}", exc)
}
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
val msg = "Photo capture succeeded: ${output.savedUri}"
Toast.makeText(requireContext(), msg, Toast.LENGTH_SHORT).show()
Timber.d(msg)
val uriFilePath = output.savedUri?.path
val path: String = uriFilePath.toString()
val bundle = Bundle()
bundle.putString("image", path)
Navigation.findNavController(requireView()).navigate(R.id
.cameraFragmentToCameraFinalFragment, bundle)
}
})
}
private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
ContextCompat.checkSelfPermission(
requireContext(), it
) == PackageManager.PERMISSION_GRANTED
}
private fun startCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())
cameraProviderFuture.addListener({
// Used to bind the lifecycle of cameras to the lifecycle owner
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
// Preview
val preview = Preview.Builder()
.build()
.also { preview ->
preview.setSurfaceProvider(binding.viewFinder.surfaceProvider)
}
imageCapture = ImageCapture.Builder()
.build()
val imageAnalyzer = ImageAnalysis.Builder()
.setTargetResolution(Size(1280, 720))
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build()
.also {
it.setAnalyzer(cameraExecutor, LuminosityAnalyzer { luma ->
Timber.d("Average luminosity: $luma")
})
}
// Select back camera as a default
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
try {
// Unbind use cases before rebinding
cameraProvider.unbindAll()
// Bind use cases to camera
cameraProvider.bindToLifecycle(
this, cameraSelector, preview, imageCapture, imageAnalyzer
)
} catch (exc: Exception) {
Timber.e("Use case binding failed", exc)
}
}, ContextCompat.getMainExecutor(requireContext()))
}
override fun onRequestPermissionsResult(
requestCode: Int, permissions: Array, grantResults:
IntArray
) {
if (requestCode == REQUEST_CODE_PERMISSIONS) {
if (allPermissionsGranted()) {
startCamera()
} else {
Toast.makeText(
requireContext(), "Permissions not granted by the user.",
Toast.LENGTH_SHORT
).show()
}
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
cameraExecutor.shutdown()
}
companion object {
private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
private const val REQUEST_CODE_PERMISSIONS = 10
private val REQUIRED_PERMISSIONS = mutableListOf(
Manifest.permission.CAMERA,
).apply {
if (Build.VERSION.SDK_INT
Подробнее здесь: https://stackoverflow.com/questions/728 ... pi-android
Как отобразить изображение, полученное с помощью Camerax API (Android) ⇐ Android
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Полученное завершение настраиваемого удара, полученное из текста справки
Anonymous » » в форуме Linux - 0 Ответы
- 18 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Я хочу ограничить полученное изображение от ImputStream до <10K (Android, Kotlin)
Anonymous » » в форуме Android - 0 Ответы
- 7 Просмотры
-
Последнее сообщение Anonymous
-