CameraX capture only the rectangular area

1,235 views
Skip to first unread message

edwin macalopú

unread,
Dec 6, 2022, 2:12:23 PM12/6/22
to Android CameraX Discussion Group
Screenshot_20221206-135502_dnirecognitiontext.jpeg

In other conversations I found 3 ways to do this rectangular capture of a specific area, and I chose this option " 2. If you want to get a higher resolution result that is cropped from ImageCapture's captured JPEG image and PreviewView is used, you may be able to use the (TransformExperimental) CoordinateTransform API to transform the rectangle position cross different types of use cases."

but I can't find how to bind my View rectangle together with CoordinateTransform


the XML is like this
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/frame"
tools:context=".CameraActivity">


<androidx.camera.view.PreviewView
android:id="@+id/viewFinder"
android:layout_width="match_parent"
android:layout_height="match_parent"
>

</androidx.camera.view.PreviewView>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="ESCANEE EL DOCUMENTO DE IDENTIDAD"
android:textStyle="bold"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:fontFamily="sans-serif-medium" />

<View
android:background="@drawable/background_drawable"
android:id="@+id/rectangle"
android:layout_width="380dp"
android:layout_height="250dp"
/>



</LinearLayout>


<Button
android:id="@+id/image_capture_button"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginBottom="50dp"
android:elevation="2dp"
android:background="@drawable/take_camera"
android:textColor="@color/colorAccent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>


<TextView
android:id="@+id/eyes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginBottom="20dp"
android:textColor="@color/cardview_light_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:text="resultado" />

<androidx.constraintlayout.widget.Guideline
android:id="@+id/vertical_centerline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent=".50" />

</androidx.constraintlayout.widget.ConstraintLayout>


 code ImageAnalysis

..........ImageAnalysis.Analyzer {
@SuppressLint("UnsafeOptInUsageError")
private val mImageProxyTransformFactory = ImageProxyTransformFactory()
@SuppressLint("UnsafeOptInUsageError", "SetTextI18n", "ResourceAsColor")
override fun analyze(imageProxy: ImageProxy) {

mImageProxyTransform=mImageProxyTransformFactory.getOutputTransform(imageProxy)
val transform = CoordinateTransform(mImageProxyTransform, target)


target should link it to the id of the rectangle from the xml?

can you help me with a basic example of how to use CoordinateTransform

Thank you


Xi Zhang (张熹)

unread,
Dec 6, 2022, 2:42:06 PM12/6/22
to edwin macalopú, Android CameraX Discussion Group
You are on the right track by using CoordinateTransform. Basically, it works like this:

// First, create a CoordinateTransform that represents the transformation matrix
val transform = CoordinateTransform(previewView.getOutputTransform(), mImageProxyTransform)
  
// Then transform. The "rectF" is the rectangle in the UI.
transform.mapRect(rectF)
 
After that, the "rectF" will contain the desired crop rect for you ImageProxy. Hope this helps. Let me know if you have more questions!

--
You received this message because you are subscribed to the Google Groups "Android CameraX Discussion Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to camerax-develop...@android.com.
To view this discussion on the web visit https://groups.google.com/a/android.com/d/msgid/camerax-developers/ed671457-84ad-4ca1-a44b-1d9430eaabd2n%40android.com.
Message has been deleted

edwin macalopú

unread,
Dec 6, 2022, 4:17:49 PM12/6/22
to Android CameraX Discussion Group, xi...@google.com, Android CameraX Discussion Group, edwin macalopú

Thanks I followed the instructions but now how to save the "rectF" as a cropped image? 

my current code is this Analyzer :


mImageProxyTransform=mImageProxyTransformFactory.getOutputTransform(imageProxy)

val rectf = RectF(rectangle.left.toFloat(), rectangle.top.toFloat(), rectangle.right.toFloat(), rectangle.bottom.toFloat())

runOnUiThread( Runnable() {

val transform = CoordinateTransform(previewView.getOutputTransform(), mImageProxyTransform)

transform.mapRect(rectf)

})

imageProxy.close()

Xi Zhang (张熹)

unread,
Dec 6, 2022, 5:50:06 PM12/6/22
to edwin macalopú, Android CameraX Discussion Group
How to crop an ImageProxy depends on what your ImageProxy contains. Looks like yours is from ImageAnalysis.Analyzer, right?  In that case, first, set the output format to OUTPUT_IMAGE_FORMAT_RGBA_8888 with ImageAnalysis.Builder#setOutputImageFormat .Then create a Bitmap from the ImageProxy:

var bitmap =  Bitmap.createBitmap(imageProxy.width, imageProxy.height, Bitmap.Config.ARGB_8888)
bitmap.copyPixelsFromBuffer(imageProxy.planes[0])
// Crop!
bitmap = Bitmap.createBitmap(bitmap, rect.left, rect.top, rect.width(), rect.height())

Note that this might not work on all Android devices. On some devices, the Bitmap may have different row strides. In that case, you might want to use something like the libyuv to copy the RGBA buffer.

Christian Günther

unread,
Dec 12, 2022, 5:55:43 AM12/12/22
to Android CameraX Discussion Group, xi...@google.com, Android CameraX Discussion Group, khiw...@gmail.com
This seems to me quite related to the problem i did run in, with non-matching stride after yuv-to-rgb conversion:
https://issuetracker.google.com/issues/261111885#comment3

Xi Zhang (张熹)

unread,
Dec 12, 2022, 9:52:09 AM12/12/22
to Christian Günther, Android CameraX Discussion Group, khiw...@gmail.com
Have you tried the solution? Did it work? Yeah right now you have to fix the row stride manually. We have a feature planned to provide a Bitmap directly, but there is no ETA.
Reply all
Reply to author
Forward
0 new messages