title: ML Kit Barcode process fails due to Image is already closed
body: <p>I'm looking for a few days how I can read a QR code using ML Kit and CameraX. The process of the input image returns always a failure &quot;IllegalStateException: Image is already closed&quot;. I have looked on different forums, but I can not find what I'm doing wrong. I think I'm following the Google documentation, but it won't work.</p>
  <p>This is what I'm doing in my MainActivity:</p>
  <ol>
  <li>I create a textureView which shows me the input of my camera</li>
  <li>I start my camera (after checking the necessary rights)</li>
  <li>I setup a &quot;preview&quot; use case</li>
  <li>I setup a &quot;Image Analysis&quot; use case</li>
  <li>I set an analyzer which creates an InputImage which is passed to the Barcode scanner process</li>
  <li>Set my LifeCycle with the use cases &quot;preview&quot; and &quot;image analysis&quot;</li>
  </ol>
  <p>I'm using CameraX version &quot;1.0.0-alpha04&quot; and &quot;com.google.mlkit:barcode-scanning:16.0.3&quot;.</p>
  <p><strong>build.gradle</strong></p>
  <pre><code>apply plugin: 'com.android.application'
  apply plugin: 'kotlin-android'
  apply plugin: 'kotlin-android-extensions'
  
  android {
      compileSdkVersion 30
      buildToolsVersion &quot;30.0.2&quot;
  
      defaultConfig {
          applicationId &quot;be.lapit.qrcodescanner&quot;
          minSdkVersion 21
          targetSdkVersion 30
          versionCode 1
          versionName &quot;1.0&quot;
  
          testInstrumentationRunner &quot;androidx.test.runner.AndroidJUnitRunner&quot;
      }
  
      buildTypes {
          release {
              minifyEnabled false
              proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
          }
      }
  }
  
  dependencies {
      implementation fileTree(dir: &quot;libs&quot;, include: [&quot;*.jar&quot;])
      implementation &quot;org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version&quot;
      implementation 'androidx.core:core-ktx:1.3.2'
      implementation 'androidx.appcompat:appcompat:1.2.0'
      implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
      testImplementation 'junit:junit:4.12'
      androidTestImplementation 'androidx.test.ext:junit:1.1.2'
      androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
  
      // ML Kit Barcode scanner
      implementation 'com.google.mlkit:barcode-scanning:16.0.3'
      implementation 'com.google.android.gms:play-services-mlkit-barcode-scanning:16.1.2'
  
      // CameraX
      def camerax_version = &quot;1.0.0-alpha04&quot;
      // The following line is optional, as the core library is included indirectly by camera-camera2
      implementation &quot;androidx.camera:camera-core:${camerax_version}&quot;
      implementation &quot;androidx.camera:camera-camera2:${camerax_version}&quot;
      // If you want to additionally use the CameraX Lifecycle library
      //implementation &quot;androidx.camera:camera-lifecycle:${camerax_version}&quot;
      // If you want to additionally use the CameraX View class
      //implementation &quot;androidx.camera:camera-view:1.0.0-alpha17&quot;
  
  }
  </code></pre>
  <p><strong>activity_main.xml</strong></p>
  <pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
  &lt;androidx.constraintlayout.widget.ConstraintLayout
     xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
     xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
     android:layout_width=&quot;match_parent&quot;
     android:layout_height=&quot;match_parent&quot;&gt;
  
     &lt;LinearLayout
         android:id=&quot;@+id/linearLayout&quot;
         android:layout_width=&quot;wrap_content&quot;
         android:layout_height=&quot;wrap_content&quot;
         android:gravity=&quot;center&quot;
         android:orientation=&quot;vertical&quot;
         app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
         app:layout_constraintEnd_toEndOf=&quot;parent&quot;
         app:layout_constraintStart_toStartOf=&quot;parent&quot;&gt;
  
  
         &lt;ImageView
             android:id=&quot;@+id/imageView&quot;
             android:layout_width=&quot;250px&quot;
             android:layout_height=&quot;250px&quot;
             android:layout_marginBottom=&quot;48dp&quot;
             android:src=&quot;@drawable/thumb_up&quot; /&gt;
  
         &lt;TextView
             android:layout_width=&quot;wrap_content&quot;
             android:layout_height=&quot;wrap_content&quot;
             android:text=&quot;Test textview&quot;/&gt;
  
         &lt;TextureView
             android:id=&quot;@+id/texture_view&quot;
             android:layout_width=&quot;600px&quot;
             android:layout_height=&quot;600px&quot; /&gt;
  
  
     &lt;/LinearLayout&gt;
  
  &lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;
  </code></pre>
  <p><strong>MainActivity.kt</strong></p>
  <pre><code>package be.lapit.qrcodescanner
  
  import android.Manifest
  import android.content.Intent
  import android.content.pm.PackageManager
  import android.os.Bundle
  import android.util.Log
  import android.util.Size
  import android.view.TextureView
  import android.widget.Button
  import android.widget.Toast
  import androidx.appcompat.app.AppCompatActivity
  import androidx.camera.core.*
  import androidx.core.app.ActivityCompat
  import androidx.core.content.ContextCompat
  import androidx.lifecycle.LifecycleOwner
  import com.google.android.gms.tasks.OnFailureListener
  import com.google.mlkit.vision.barcode.Barcode
  import com.google.mlkit.vision.barcode.BarcodeScannerOptions
  import com.google.mlkit.vision.barcode.BarcodeScanning
  import com.google.mlkit.vision.common.InputImage
  import java.time.Instant
  import java.time.format.DateTimeFormatter
  import kotlin.system.measureTimeMillis
  
  
  class MainActivity : AppCompatActivity() {
  
      // PLA: Variable needed to check if user has granted camera permission
      companion object {
          private const val REQUEST_CAMERA_PERMISSION = 10
      }
  
      private lateinit var textureView: TextureView
  
      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_main)
  
          textureView = findViewById(R.id.texture_view)
  
          // Request camera permissions
          if (isCameraPermissionGranted()) {
              textureView.post { startCamera() }
          } else {
              ActivityCompat.requestPermissions(
                  this,
                  arrayOf(Manifest.permission.CAMERA),
                  REQUEST_CAMERA_PERMISSION
              )
          }
  
  
      }
  
      private fun startCamera() {
          // -----------------------
          // Setup use case Preview
          // -----------------------
          val previewConfig : PreviewConfig = PreviewConfig.Builder()
              // We want to show input from front camera of the device
              .setLensFacing(CameraX.LensFacing.FRONT)
              .build()
  
          val preview = Preview(previewConfig)
  
          preview.setOnPreviewOutputUpdateListener { previewOutput -&gt;
              textureView.setSurfaceTexture(previewOutput.surfaceTexture)
          }
  
          // ------------------------------
          // Setup use case Image Analysis
          // ------------------------------
          val imageAnalysisConfig = ImageAnalysisConfig.Builder()
              .setTargetResolution(Size(1280, 720))
              .setLensFacing(CameraX.LensFacing.FRONT)
              .setImageReaderMode(ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE)
              .setImageQueueDepth(1)
              .build()
  
          val imageAnalysis = ImageAnalysis(imageAnalysisConfig)
  
          // -------------------
          // Set image analyzer
          // -------------------
          imageAnalysis.setAnalyzer { imageProxy: ImageProxy, rotationDegrees: Int -&gt;
              Log.i(&quot;Status&quot;, &quot;In setAnalyzer on &quot; + System.currentTimeMillis())
  
              val mediaImage = imageProxy.image
              if (mediaImage != null) {
                  val image1 = InputImage.fromMediaImage(mediaImage, rotationDegrees)
  
                  // --------------------------
                  // Configure barcode scanner
                  // --------------------------
                  val barcodeScannerOptions: BarcodeScannerOptions = BarcodeScannerOptions.Builder()
                      .setBarcodeFormats(
                          Barcode.FORMAT_QR_CODE,
                          Barcode.FORMAT_AZTEC,
                          Barcode.FORMAT_EAN_13
  
                      )
                      .build()
  
                  // Get an instance of BarcodeScanner
                  val scanner = BarcodeScanning.getClient(barcodeScannerOptions)
  
                  scanner.process(image1)
                      .addOnSuccessListener ({ barcodes -&gt;
                          // Task completed successfully
                          Log.i(&quot;Status&quot;, &quot;In success listener on timestamp &quot; + System.currentTimeMillis())
                          for (barcode in barcodes) {
                              Log.i(&quot;Barcode&quot;, barcode.toString())
                          }
                          Toast.makeText(this,&quot;Ik ben hier eindelijk&quot;,Toast.LENGTH_LONG).show();
  
                      })
                      .addOnFailureListener(OnFailureListener {
                          // Process failed
                          Log.i(&quot;Status&quot;, &quot;In failure listener on &quot; +  System.currentTimeMillis() + &quot; because: $it&quot;)
                          Log.i(&quot;Failure&quot;, &quot;$it&quot;)
                          it.printStackTrace()
                      })
                      .addOnCompleteListener {
                          Log.i(&quot;Status&quot;, &quot;In complete listener on &quot; +  System.currentTimeMillis())
                          //imageProxy.close()
                      }
              }
          }
  
          // Bind
          CameraX.bindToLifecycle(this as LifecycleOwner, preview, imageAnalysis)
      }
  
  
      private fun isCameraPermissionGranted(): Boolean {
          val selfPermission = ContextCompat.checkSelfPermission(
              baseContext,
              Manifest.permission.CAMERA
          )
          return selfPermission == PackageManager.PERMISSION_GRANTED
      }
  
      override fun onRequestPermissionsResult(
          requestCode: Int,
          permissions: Array&lt;String&gt;,
          grantResults: IntArray
      ) {
          if (requestCode == REQUEST_CAMERA_PERMISSION) {
              if (isCameraPermissionGranted()) {
                  textureView.post { startCamera() }
              } else {
                  Toast.makeText(this, &quot;Camera permission is required.&quot;, Toast.LENGTH_SHORT).show()
                  finish()
              }
          }
      }
  }
  </code></pre>
  <p><strong>Logging info</strong></p>
  <pre><code>I/Status: In setAnalyzer on 1602190069609
  I/tflite: Initialized TensorFlow Lite runtime.
  I/native: barcode_detector_client.cc:238 Not using NNAPI
  I/Status: In failure listener on 1602190069612 because: com.google.mlkit.common.MlKitException: Internal error has occurred when executing ML Kit tasks
  I/Failure: com.google.mlkit.common.MlKitException: Internal error has occurred when executing ML Kit tasks
  W/System.err: com.google.mlkit.common.MlKitException: Internal error has occurred when executing ML Kit tasks
          at com.google.mlkit.common.sdkinternal.ModelResource.zza(com.google.mlkit:common@@17.0.0:32)
          at com.google.mlkit.common.sdkinternal.zzl.run(com.google.mlkit:common@@17.0.0)
  W/System.err:     at com.google.mlkit.common.sdkinternal.zzp.run(com.google.mlkit:common@@17.0.0:3)
          at com.google.mlkit.common.sdkinternal.MlKitThreadPool.zzd(com.google.mlkit:common@@17.0.0:24)
          at com.google.mlkit.common.sdkinternal.MlKitThreadPool.zza(com.google.mlkit:common@@17.0.0:30)
          at com.google.mlkit.common.sdkinternal.zzh.run(com.google.mlkit:common@@17.0.0)
          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
          at java.lang.Thread.run(Thread.java:762)
      Caused by: java.lang.IllegalStateException: Image is already closed
          at android.media.Image.throwISEIfImageIsInvalid(Image.java:68)
          at android.media.ImageReader$SurfaceImage$SurfacePlane.getBuffer(ImageReader.java:803)
          at com.google.mlkit.vision.barcode.internal.zzf.zza(com.google.android.gms:play-services-mlkit-barcode-scanning@@16.1.2:72)
          at com.google.mlkit.vision.barcode.internal.zzf.zzb(com.google.android.gms:play-services-mlkit-barcode-scanning@@16.1.2:83)
          at com.google.mlkit.vision.barcode.internal.zzf.run(com.google.android.gms:play-services-mlkit-barcode-scanning@@16.1.2:143)
          at com.google.mlkit.vision.common.internal.MobileVisionBase.zza(com.google.mlkit:vision-common@@16.1.0:23)
          at com.google.mlkit.vision.common.internal.zzc.call(com.google.mlkit:vision-common@@16.1.0)
          at com.google.mlkit.common.sdkinternal.ModelResource.zza(com.google.mlkit:common@@17.0.0:29)
          ... 8 more
  I/Status: In complete listener on 1602190069614
      In failure listener on 1602190069614 because: com.google.mlkit.common.MlKitException: Internal error has occurred when executing ML Kit tasks
  I/Failure: com.google.mlkit.common.MlKitException: Internal error has occurred when executing ML Kit tasks
  W/System.err: com.google.mlkit.common.MlKitException: Internal error has occurred when executing ML Kit tasks
          at com.google.mlkit.common.sdkinternal.ModelResource.zza(com.google.mlkit:common@@17.0.0:32)
          at com.google.mlkit.common.sdkinternal.zzl.run(com.google.mlkit:common@@17.0.0)
          at com.google.mlkit.common.sdkinternal.zzp.run(com.google.mlkit:common@@17.0.0:3)
          at com.google.mlkit.common.sdkinternal.MlKitThreadPool.zzd(com.google.mlkit:common@@17.0.0:24)
          at com.google.mlkit.common.sdkinternal.MlKitThreadPool.zza(com.google.mlkit:common@@17.0.0:30)
          at com.google.mlkit.common.sdkinternal.zzh.run(com.google.mlkit:common@@17.0.0)
          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
          at java.lang.Thread.run(Thread.java:762)
  W/System.err: Caused by: java.lang.IllegalStateException: Image is already closed
          at android.media.Image.throwISEIfImageIsInvalid(Image.java:68)
          at android.media.ImageReader$SurfaceImage$SurfacePlane.getBuffer(ImageReader.java:803)
          at com.google.mlkit.vision.barcode.internal.zzf.zza(com.google.android.gms:play-services-mlkit-barcode-scanning@@16.1.2:72)
          at com.google.mlkit.vision.barcode.internal.zzf.zzb(com.google.android.gms:play-services-mlkit-barcode-scanning@@16.1.2:83)
          at com.google.mlkit.vision.barcode.internal.zzf.run(com.google.android.gms:play-services-mlkit-barcode-scanning@@16.1.2:143)
          at com.google.mlkit.vision.common.internal.MobileVisionBase.zza(com.google.mlkit:vision-common@@16.1.0:23)
          at com.google.mlkit.vision.common.internal.zzc.call(com.google.mlkit:vision-common@@16.1.0)
          at com.google.mlkit.common.sdkinternal.ModelResource.zza(com.google.mlkit:common@@17.0.0:29)
          ... 8 more
  I/Status: In complete listener on 1602190069615
  </code></pre>