My barcode reader runs well but I want user can only scan barcode what is inside in view area to detect. I wrote a code for it. I can get cornerPoints
of barcode that scanned but I can't realize if it's inside my detection view. I can't see rect
value of view
that passed from fragment to BarcodeAnalyzer class in debug mode. I don't know wether it is problem to achieve this or not.
BarcodeReaderFragment.kt
val imageAnalyzer = ImageAnalysis.Builder()
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build()
.also {
val rect = Rect()
binding.viewFocusArea.getGlobalVisibleRect(rect)
it.setAnalyzer(
cameraExecutor, BarcodeAnalyzer(
rect,
::barcodeListener
)
)
}
BarcodeAnalyzer.kt
class BarcodeAnalyzer(
private val rectArea: Rect,
private val barcodeListener: (barcode: String) -> Unit
) : ImageAnalysis.Analyzer {
.addOnCompleteListener {
image.close()
if (it.isSuccessful) {
val barcodes = it.result as List<Barcode>
// Task completed successfully
for (barcode in barcodes) {
val cornerTL = barcode.cornerPoints?.get(0)
val cornerTR = barcode.cornerPoints?.get(1)
val cornerBL = barcode.cornerPoints?.get(2)
val cornerBR = barcode.cornerPoints?.get(3)
cornerTL?.let { topLeft ->
cornerTR?.let { topRight ->
cornerBR?.let { bottomRight ->
cornerBL?.let { bottomLeft ->
if (rectArea.contains(topLeft) && rectArea.contains(topRight) && rectArea.contains(bottomRight) && rectArea.contains(
bottomLeft
)
) {
barcodeListener(barcode.rawValue ?: "")
}
}
}
fragment_barcode_reader.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.camera.view.PreviewView
android:id="@+id/preview_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<View
android:id="@+id/viewRightTopVCorner"
android:layout_width="12dp"
android:layout_height="1dp"
android:layout_marginEnd="-4dp"
android:layout_marginBottom="5dp"
android:background="@color/white"
app:layout_constraintBottom_toTopOf="@+id/viewFocusArea"
app:layout_constraintEnd_toEndOf="@+id/viewFocusArea" />
<View
android:id="@+id/viewRightTopHCorner"
android:layout_width="1dp"
android:layout_height="12dp"
android:background="@color/white"
app:layout_constraintEnd_toEndOf="@+id/viewRightTopVCorner"
app:layout_constraintTop_toBottomOf="@+id/viewRightTopVCorner" />
<View
android:id="@+id/viewRightBottomVCorner"
android:layout_width="12dp"
android:layout_height="1dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="-4dp"
android:background="@color/white"
app:layout_constraintEnd_toEndOf="@+id/viewFocusArea"
app:layout_constraintTop_toBottomOf="@+id/viewFocusArea" />
<View
android:id="@+id/viewRightBottomHCorner"
android:layout_width="1dp"
android:layout_height="12dp"
android:background="@color/white"
app:layout_constraintEnd_toEndOf="@+id/viewRightBottomVCorner"
app:layout_constraintBottom_toTopOf="@+id/viewRightBottomVCorner" />
<View
android:id="@+id/viewLeftBottomVCorner"
android:layout_width="12dp"
android:layout_height="1dp"
android:layout_marginStart="-4dp"
android:layout_marginTop="5dp"
android:background="@color/white"
app:layout_constraintStart_toStartOf="@+id/viewFocusArea"
app:layout_constraintTop_toBottomOf="@+id/viewFocusArea" />
<View
android:id="@+id/viewLeftBottomHCorner"
android:layout_width="1dp"
android:layout_height="12dp"
android:background="@color/white"
app:layout_constraintBottom_toTopOf="@+id/viewLeftBottomVCorner"
app:layout_constraintStart_toStartOf="@+id/viewLeftBottomVCorner" />
<View
android:id="@+id/viewLeftTopVCorner"
android:layout_width="12dp"
android:layout_height="1dp"
android:layout_marginStart="-4dp"
android:layout_marginBottom="5dp"
android:background="@color/white"
app:layout_constraintBottom_toTopOf="@+id/viewFocusArea"
app:layout_constraintStart_toStartOf="@+id/viewFocusArea" />
<View
android:id="@+id/viewLeftTopHCorner"
android:layout_width="1dp"
android:layout_height="12dp"
android:background="@color/white"
app:layout_constraintTop_toBottomOf="@+id/viewLeftTopVCorner"
app:layout_constraintStart_toStartOf="@+id/viewLeftTopVCorner" />
<View
android:id="@+id/viewFocusArea"
android:layout_width="0dp"
android:layout_height="101dp"
android:layout_marginStart="48dp"
android:layout_marginTop="35dp"
android:layout_marginEnd="47dp"
android:background="#00FFFFFF"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/preview_view"
app:layout_constraintTop_toBottomOf="@+id/txtBarcodeScan" />
<View
android:id="@+id/shadow_top"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="-4dp"
android:background="#80000000"
app:layout_constraintBottom_toTopOf="@+id/viewFocusArea"
app:layout_constraintEnd_toStartOf="@+id/shadow_right"
app:layout_constraintStart_toEndOf="@+id/shadow_left"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="invisible" />
<View
android:id="@+id/shadow_bottom"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="-4dp"
android:background="#80000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/shadow_right"
app:layout_constraintStart_toEndOf="@+id/shadow_left"
app:layout_constraintTop_toBottomOf="@+id/viewFocusArea"
tools:visibility="invisible" />
<View
android:id="@+id/shadow_left"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="-4dp"
android:background="#80000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/viewFocusArea"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="invisible" />
<View
android:id="@+id/shadow_right"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="-4dp"
android:background="#80000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/preview_view"
app:layout_constraintStart_toEndOf="@+id/viewFocusArea"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="invisible" />
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
app:layout_constraintEnd_toEndOf="@+id/preview_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_identity_hexagon" />
<TextView
android:id="@+id/txtBarcodeScan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Lütfen fiyatını öğrenmek istediğin \nürünün barkodunu okut"
android:textColor="@color/white"
android:gravity="center"
android:fontFamily="@font/poppins_regular"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/image" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btnChangeShop"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="55dp"
android:backgroundTint="@color/dull_orange"
android:fontFamily="@font/poppins_semibold"
android:insetTop="0dp"
android:insetBottom="0dp"
android:letterSpacing="0"
app:cornerRadius="4dp"
android:paddingVertical="15dp"
android:text="@string/click_to_change_shop"
android:textAllCaps="false"
android:textColor="@color/white"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Just in case you still need it.
I've coded a snippet to test the transformation of the imageProxy coordinates to the preview coordinates using the Java version of the snippet found at :https://developer.android.com/training/camerax/transform-output.
The barcode is detected when its view enters the rectangle view located at height = previewView.getHeight()/5 and width = preview.getWidth()/2.
Conclusion : the detection works very well.
I assume that you want to detect the barcode when it enters this ImageView!
You must determine the coordinates of the center of this image. These coordinates are the xp and yp coordinates I use in my snippet above.