Я застрял с, казалось бы, простой задачей: после съемки изображения отобразить это изображение в полном ViewPort CameraPreview.
Ответы на связанные вопросы не решили мою проблему (как я объясню ниже).
Попытка получить растровое изображение, которое я получаю от прослушивателя onCaptureSuccess ImageCapture, для масштабирования просто не работает.
Я пытался сделать это с помощью «классическая» настройка с использованием CameraProvider и привязка к ней моих вариантов использования Preview и ImageCapture, прежде чем я изменил свой подход к использованию подхода AndroidX CameraController. В обоих случаях я позаботился об одном и том же ViewPort для обоих вариантов использования, попытался изменить размер/обрезать полученное изображение, чтобы оно имело то же соотношение сторон/разрешение, что и у предварительного просмотра, поэкспериментировал со свойством корректировкиViewBounds, безуспешно, изображение всегда будет в центре предварительного просмотра, но масштабировано вниз (я знаю, что результирующее разрешение по умолчанию намного выше, чем разрешение моего экрана, я не против масштабировать изображение или обрезать его, пока оно заполняет все screen):
Скриншот фотографии, не занимающий всю область предварительного просмотра
Соответствующие части моего кода:
Файл макета
CameraFragment
Инициализация варианта использования предварительного просмотра и ImageView:
private lateinit var imagePreview: ImageView
private lateinit var viewFinder: PreviewView
private lateinit var cameraController: LifecycleCameraController
private var imageCapture: ImageCapture? = null
private lateinit var preview: Preview
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
cameraView = inflater.inflate(R.layout.fragment_camera, container, false)
cameraView.viewTreeObserver.addOnGlobalLayoutListener(onGlobalLayoutListener)
imagePreview = cameraView.findViewById(R.id.image_preview)
imagePreview.isVisible = false
val previewView: PreviewView = cameraView.findViewById(R.id.viewFinder)
previewView.controller = cameraController
...
return cameraView
}
startCamera(), вызываемый в onCreate() фрагмента:
private fun startCamera() {
cameraController = LifecycleCameraController(requireContext())
cameraController.bindToLifecycle(this)
}
Реализация takePicture() для объекта cameraController:
cameraController.takePicture(ContextCompat.getMainExecutor(requireContext()),
object : ImageCapture.OnImageCapturedCallback() {
override fun onCaptureSuccess(image: ImageProxy) {
Log.d("ImageCapture", "Success")
val buffer = image.planes[0].buffer
val bytes = ByteArray(buffer.capacity())
buffer[bytes]
val bitmapImage = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
imagePreview.rotation = image.imageInfo.rotationDegrees.toFloat()
imagePreview.setImageBitmap(bitmapImage)
imagePreview.isVisible = true
}
override fun onError(exception: ImageCaptureException) {
Log.e("ImageCapture", "Failed to capture image: $exception")
super.onError(exception)
}
})
Как объяснялось ранее, я больше не обрезаю изображение (потому что, насколько я понимаю, LifeCycleController делает это за вас) - хотя я и раньше пробовал подходы к обрезке с этим, но безуспешно.
Подходы к обрезке включали: обрезку и изменение размера до точного размера устройства/окна просмотра с использованием объекта Crottrect ImageProxy.
Я начинаю думать, что моя проблема - это простой ImageView Проблема с макетом, а не с камерой?
Изменить
Обрезка imageProxy таким образом тоже не помогает:
val croppedBitmap = Bitmap.createBitmap(
bitmapImage,
image.cropRect.left,
image.cropRect.top,
image.cropRect.width(),
image.cropRect.height()
)
Подробнее здесь: https://stackoverflow.com/questions/753 ... ler-to-fil