mrousavy / react-native-vision-camera

📸 A powerful, high-performance React Native Camera library.
https://react-native-vision-camera.com
MIT License
7.54k stars 1.1k forks source link

🐛 InputImage.zzb - java.lang.IllegalStateException - Image is already closed #2724

Closed shravanETS closed 6 months ago

shravanETS commented 7 months ago

What's happening?

I received an error in production and encountered a crash in Firebase Crashlytics. However, when I attempted to reproduce it, I couldn't replicate the crash.

Below device and version affected : Screenshot 2024-04-08 at 10 36 00 AM Screenshot 2024-04-08 at 10 36 05 AM

Reproduceable Code

const { hasPermission, requestPermission } = useCameraPermission();
  const [isCameraInitialized, setIsCameraInitialized] = useState(false);

  const isActive =
    isFocused &&
    isForeground &&
    !isKeyboardVisible &&
    !isScanned &&
    !isLoading

// some code 

 const codeScanner = useCodeScanner({
    codeTypes: ["qr", "ean-13"],
    onCodeScanned: (codes) => {
      setisScanned(true);
      const val = codes[0];
      // simpleToast(codes[0].value as string);
      setisScanned(true);
      if (!isgetscanqrcode) {
        if (scanQrCode.length < 1) {
          Vibration.vibrate(300);
          setisGetScanQrCode(true);
          let scanValue = "";
          if (val.value?.toString().includes("21/")) {
            consoleLogs(val.value, "https");
            scanValue = getCodeFromUrl(val.value as string);
            if (scanValue.length != 13 && scanValue.length != 12) {
              setTimeout(() => {
                setisGetScanQrCode(false);
              }, 300);
            } else {
              scanValue = getCodeFromUrl(val.value as string);
            }
          } else {
            consoleLogs(val.value, " ");
            if (
              val.value?.toString().trim().length != 13 &&
              val.value?.toString().trim().length != 12
            ) {
              setTimeout(() => {
                setisGetScanQrCode(false);
              }, 300);
            } else {
              setScanQrCode([...scanQrCode, val.value.toString().trim()]);
              scanValue = val.value as string;
            }
          }
          if (scanValue.trim().length != 13 && scanValue.trim().length != 12) {
            setTimeout(() => {
              setIsSingleScanFailedVisible(true);
              setIsErrorString(t("earningerrors.invalid"));
              setIsErrorStringDetail(t("earningerrors.invaliddetail"));
            }, 300);
          } else {
            if (
              type === userForAnalytics.painterType &&
              scanValue.trim().length < 13
            ) {
              setIsSingleScanFailedVisible(true);
              setIsErrorString(t("earningerrors.eligible"));
              setIsErrorStringDetail(t("earningerrors.eligibledescription"));
              setisGetScanQrCode(false);
              setScanQrCode([]);
            } else {
              ScanCode([scanValue], "Camera");
            }
          }
        }
      }
    },
  });

// some code 

        <ScrollView
        contentContainerStyle={{ flexGrow: 1 }}
        bounces={false}
        keyboardShouldPersistTaps="handled"
      >
        {device != null && hasPermission && (
          <Camera
            style={
              isCameraInitialized
                ? StyleSheet.absoluteFill
                : [
                    {
                      height: gWindowHeight,
                      width: 0,
                      aspectRatio: gWindowHeight / gWindowWidth,
                    },
                    StyleSheet.absoluteFill,
                  ]
            }
            device={device}
            onInitialized={() => {
              setTimeout(() => {
                setIsCameraInitialized(true);
              }, 120);
            }}
            isActive={isActive}
            torch={isTorchOn ? "on" : "off"}
            codeScanner={codeScanner}
            video={false}
            photo={false}
            audio={false}
            onError={(error) => {
              // console.log(error);
            }}
          />
        )}
    <>
    {/*Some code */}
    </>
    </ScrollView>

Relevant log output

Fatal Exception: java.lang.IllegalStateException: Image is already closed
       at android.media.Image.throwISEIfImageIsInvalid(Image.java:70)
       at android.media.ImageReader$SurfaceImage.getFormat(ImageReader.java:821)
       at com.google.mlkit.vision.common.InputImage.zzb(InputImage.java:12)
       at com.google.mlkit.vision.common.InputImage.fromMediaImage(InputImage.java:1)
       at com.mrousavy.camera.core.CodeScannerPipeline._init_$lambda$4(CodeScannerPipeline.java:34)
       at android.media.ImageReader$ListenerHandler.handleMessage(ImageReader.java:800)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:201)
       at android.os.HandlerThread.run(HandlerThread.java:65)

Camera Device

{}

Device

Vivo, Oppo , Xiaomi

VisionCamera Version

4.0.0-beta.10

Can you reproduce this issue in the VisionCamera Example app?

I didn't try (⚠️ your issue might get ignored & closed if you don't try this)

Additional information

mrousavy commented 7 months ago

I need log output for this. ADB does also log in production, no?

shravanETS commented 7 months ago

I need log output for this. ADB does also log in production, no?

firebase-crashlytics-stacktrace.txt

It's found in production, so I have the Firebase stack trace. I can't reproduce it in development.

mrousavy commented 7 months ago

This is just the tombstone/stacktrace, are there any logs? I need to know what happened before this crash.

shravanETS commented 7 months ago

Crashlytics - Custom logs

Application: com.packagename

Platform: android

Date: Wed Apr 10 2024 16:11:34 GMT+0530 (India Standard Time)

0 | Wed Apr 10 2024 16:10:40 GMT+0530 (India Standard Time) | screen_view (MainActivity) 1 | Wed Apr 10 2024 16:10:45 GMT+0530 (India Standard Time) | mounted screen: SplashScreen 2 | Wed Apr 10 2024 16:10:51 GMT+0530 (India Standard Time) | mounted screen: HomeScreen 3 | Wed Apr 10 2024 16:10:52 GMT+0530 (India Standard Time) | screen_view (HomeScreen) 4 | Wed Apr 10 2024 16:11:03 GMT+0530 (India Standard Time) | Click on Scan 5 | Wed Apr 10 2024 16:11:03 GMT+0530 (India Standard Time) | mounted screen: ScanScreen 6 | Wed Apr 10 2024 16:11:04 GMT+0530 (India Standard Time) | screen_view (ScanScreen) 7 | Wed Apr 10 2024 16:11:30 GMT+0530 (India Standard Time) | Code Scanner Start 8 | Wed Apr 10 2024 16:11:31 GMT+0530 (India Standard Time) | Code Scanner Complete

When Code Scanner Start we show the loader ( modal )
When Code Scanner Complete we close the loader ( modal )

margabit commented 7 months ago

I have the same issue on Android 13 Oppo A18

Fatal Exception: java.lang.IllegalStateException: Image is already closed
       at android.media.Image.throwISEIfImageIsInvalid(Image.java:79)
       at android.media.ImageReader$SurfaceImage.getFormat(ImageReader.java:1158)
       at com.google.mlkit.vision.common.InputImage.zzb(com.google.mlkit:vision-common@@17.3.0:8)
       at com.google.mlkit.vision.common.InputImage.fromMediaImage(com.google.mlkit:vision-common@@17.3.0:1)
       at com.mrousavy.camera.core.CodeScannerPipeline._init_$lambda$4(CodeScannerPipeline.kt:53)
       at com.mrousavy.camera.core.CodeScannerPipeline.$r8$lambda$J9uS5V_QrF4Y46dODUvYa6w1Wm0()
       at com.mrousavy.camera.core.CodeScannerPipeline$$ExternalSyntheticLambda0.onImageAvailable(:4)
       at android.media.ImageReader$1.run(ImageReader.java:916)
       at android.os.Handler.handleCallback(Handler.java:942)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loopOnce(Looper.java:240)
       at android.os.Looper.loop(Looper.java:351)
       at android.os.HandlerThread.run(HandlerThread.java:67)
mrousavy commented 6 months ago

Hey - I think this issue has been fixed in VisionCamera 4.0.0. 🥳

Please try V4 and let me know if you still experience this issue;

pke commented 6 months ago

Version 4 has different dependencies with who knows what side effects. A simple try/catch around the CodeScannerPipeline lambda would probably fix this issue even in V3.

mrousavy commented 6 months ago

A simple try/catch around the CodeScannerPipeline lambda would probably fix this issue even in V3.

A PR would be much appreciated :)