无法在Android中从CameraX正确裁剪图像

xzabzqsa  于 2023-01-19  发布在  Android
关注(0)|答案(1)|浏览(194)

我正在尝试使用CameraX.

在矩形内捕获图像,如图所示
我的方法是,计算屏幕与捕获图像的比例,然后将相机中可见的矩形Map到另一个矩形(相当于捕获的图像),然后裁剪位图。代码如下所示。
fragment_scan_doc.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/clRoot"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/gdl_left"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="28dp" />

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/margin_25dp"
        android:text="@string/app_name"
        android:textColor="@color/black"
        android:textSize="@dimen/text_size_24sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="@id/gdl_right"
        app:layout_constraintStart_toStartOf="@id/gdl_left"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tvDesc"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/margin_16dp"
        android:text="@string/place_doc"
        android:textColor="@color/black"
        app:layout_constraintEnd_toEndOf="@+id/gdl_right"
        app:layout_constraintStart_toStartOf="@+id/gdl_left"
        app:layout_constraintTop_toBottomOf="@+id/tvTitle" />

    <androidx.camera.view.PreviewView
        android:id="@+id/previewView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="@dimen/dimen_24dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tvDesc" />

    <TextView
        android:id="@+id/tvCamera"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="13dp"
        android:background="@drawable/bg_round_white_solid_yellow_stripe"
        android:gravity="center"
        android:paddingStart="@dimen/dimen_25dp"
        android:paddingTop="@dimen/dimen_10dp"
        android:paddingEnd="@dimen/dimen_25dp"
        android:paddingBottom="@dimen/dimen_10dp"
        android:text="Front"
        android:textColor="@color/black"
        app:layout_constraintEnd_toEndOf="@id/gdl_right"
        app:layout_constraintStart_toStartOf="@id/gdl_left"
        app:layout_constraintTop_toTopOf="@+id/previewView" />

    <View
        android:id="@+id/border_view"
        android:layout_width="325dp"
        android:layout_height="202.5010436dp"
        android:background="@drawable/bg_round_grey_stripe"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="@id/gdl_right"
        app:layout_constraintStart_toStartOf="@id/gdl_left"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tvPoweredBy"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:text="Powered by"
        android:textColor="@color/white"
        app:layout_constraintEnd_toEndOf="@id/gdl_right"
        app:layout_constraintStart_toStartOf="@id/gdl_left"
        app:layout_constraintTop_toBottomOf="@+id/border_view" />

    <View
        android:id="@+id/vTakePhoto"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_marginBottom="20dp"
        android:background="@drawable/bg_round_white_solid_stripe"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
         />

    <ImageView
        android:id="@+id/ivFlash"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="40dp"
        android:background="@drawable/bg_circle_white_solid"
        android:padding="10dp"
        android:src="@drawable/ic_baseline_flash_off_24"
        app:layout_constraintBottom_toBottomOf="@+id/vTakePhoto"
        app:layout_constraintStart_toEndOf="@+id/vTakePhoto"
        app:layout_constraintTop_toTopOf="@+id/vTakePhoto" />

    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:elevation="50dp"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/gdl_right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_end="28dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

在这里,我从camerax获取Image,并将其提交给cropImage()函数

private fun takePhoto() {

        imageCapture?.takePicture(ContextCompat.getMainExecutor(requireContext()),
            object : ImageCapture.OnImageCapturedCallback() {
                @SuppressLint("UnsafeOptInUsageError")
                override fun onCaptureSuccess(imageProxy: ImageProxy) {

                    

                    val image = imageProxy.image?.let { image ->
                        InputImage.fromMediaImage(
                            image,
                            imageProxy.imageInfo.rotationDegrees
                        )
                    }
                    cropImage(imageProxy)
                }

                override fun onError(exception: ImageCaptureException) {
                    exception.printStackTrace()
                }
            })

}

这是cropImage()函数

private fun cropImage(imageProxy: ImageProxy) {
        val ori = imageProxy.convertImageProxyToBitmap().rotate(90f)

        val rect = Rect()

        mViewBinding.borderView.getGlobalVisibleRect(rect)

        val screenWidth = mViewBinding.root.width
        val screenHeight = mViewBinding.root.height

        val ratioW = screenWidth.toFloat() / ori.width // I am trying to get the ratio of screen to image width
        val ratioH = screenHeight.toFloat() / ori.height

        val x1 = rect.left / ratioW
        val y1 = rect.top / ratioH
        val x1W = rect.right / ratioW
        val x1H = rect.bottom / ratioH

        val rect1 = Rect(x1.toInt(), y1.toInt(), x1W.toInt(), x1H.toInt())

        val cropedBm = Bitmap.createBitmap(
            ori,
            rect1.left,
            rect1.top,
            rect1.right - rect1.left,
            rect1.bottom - rect1.top
        )
        processNewBitmap(cropedBm) // this is where I display the cropped bitmap and it appears like in the image below
    }

图像被裁剪到矩形框下方一点。
我不太确定我做错了什么。任何帮助或指导都将不胜感激。谢谢

s3fp2yjn

s3fp2yjn1#

你的ImageProxy有一个位图,你想用一个宽度或高度不同的视图覆盖来裁剪它。2你必须用缩放比例来计算。
您可以访问此链接:https://www.codeproject.com/Articles/1276135/Crop-Image-from-Camera-on-Android

相关问题