gev2002 / react-native-vision-camera-text-recognition

https://www.npmjs.com/package/react-native-vision-camera-text-recognition
MIT License
49 stars 9 forks source link

Frame drops #16

Closed DaveVaval closed 1 month ago

DaveVaval commented 1 month ago

Using this plugin I get really bad frame drops. I tried many things, but nothing seems to work. The react-native-vision-camera documentation doesn't quite give a consice way of fixing this issue.

"react-native-vision-camera": "^4.5.3", "react-native-vision-camera-text-recognition": "^3.1.1", "react-native-worklets-core": "^1.3.3",

denisbevilacqua commented 1 month ago

Hey @DaveVaval! You can try using something like this:

import { runOnJS } from 'react-native-reanimated';
import { runAtTargetFps, useFrameProcessor } from 'react-native-vision-camera';
import { useTextRecognition } from 'react-native-vision-camera-text-recognition';
import type { TextRecognitionOptions } from 'react-native-vision-camera-text-recognition/src/types';

type UseCustomFrameProcessor Props = {
  onTextScanned?: (text: string) => void;
};

const useCustomFrameProcessor = ({ onTextScanned }: UseCustomFrameProcessor) => {
  const options: TextRecognitionOptions = { language: 'latin' };
  const { scanText } = useTextRecognition(options);

  const onTextDetected = Worklets.createRunOnJS((text: string) => {
    if (onTextScanned) runOnJS(onTextScanned)(text);
  });

  const frameProcessor = useFrameProcessor(frame => {
    'worklet';

    runAtTargetFps(0.5, () => {
      'worklet';
      let data = scanText(frame);

      try {
        // @ts-ignore
        data?.blocks.map(item => {
          // Use your own pattern in order to detect a specific text
          const eightNumbersPattern = /^(\d\s?){8}$/;

          if (eightNumbersPattern.test(item.blockText)) {
            onTextDetected(item.blockText);
          }
        });
      } catch (e) {}
    });
  }, []);

  return {
    frameProcessor,
  };
};
DaveVaval commented 1 month ago

Hey @DaveVaval! You can try using something like this:

import { runOnJS } from 'react-native-reanimated';
import { runAtTargetFps, useFrameProcessor } from 'react-native-vision-camera';
import { useTextRecognition } from 'react-native-vision-camera-text-recognition';
import type { TextRecognitionOptions } from 'react-native-vision-camera-text-recognition/src/types';

type UseCustomFrameProcessor Props = {
  onTextScanned?: (text: string) => void;
};

const useCustomFrameProcessor = ({ onTextScanned }: UseCustomFrameProcessor) => {
  const options: TextRecognitionOptions = { language: 'latin' };
  const { scanText } = useTextRecognition(options);

  const onTextDetected = Worklets.createRunOnJS((text: string) => {
    if (onTextScanned) runOnJS(onTextScanned)(text);
  });

  const frameProcessor = useFrameProcessor(frame => {
    'worklet';

    runAtTargetFps(0.5, () => {
      'worklet';
      let data = scanText(frame);

      try {
        // @ts-ignore
        data?.blocks.map(item => {
          // Use your own pattern in order to detect a specific text
          const eightNumbersPattern = /^(\d\s?){8}$/;

          if (eightNumbersPattern.test(item.blockText)) {
            onTextDetected(item.blockText);
          }
        });
      } catch (e) {}
    });
  }, []);

  return {
    frameProcessor,
  };
};

Thank you very much!❤️❤️

denisbevilacqua commented 1 month ago

Hey @DaveVaval! You can try using something like this:

import { runOnJS } from 'react-native-reanimated';
import { runAtTargetFps, useFrameProcessor } from 'react-native-vision-camera';
import { useTextRecognition } from 'react-native-vision-camera-text-recognition';
import type { TextRecognitionOptions } from 'react-native-vision-camera-text-recognition/src/types';

type UseCustomFrameProcessor Props = {
  onTextScanned?: (text: string) => void;
};

const useCustomFrameProcessor = ({ onTextScanned }: UseCustomFrameProcessor) => {
  const options: TextRecognitionOptions = { language: 'latin' };
  const { scanText } = useTextRecognition(options);

  const onTextDetected = Worklets.createRunOnJS((text: string) => {
    if (onTextScanned) runOnJS(onTextScanned)(text);
  });

  const frameProcessor = useFrameProcessor(frame => {
    'worklet';

    runAtTargetFps(0.5, () => {
      'worklet';
      let data = scanText(frame);

      try {
        // @ts-ignore
        data?.blocks.map(item => {
          // Use your own pattern in order to detect a specific text
          const eightNumbersPattern = /^(\d\s?){8}$/;

          if (eightNumbersPattern.test(item.blockText)) {
            onTextDetected(item.blockText);
          }
        });
      } catch (e) {}
    });
  }, []);

  return {
    frameProcessor,
  };
};

Thank you very much!❤️❤️

No problem! Please let me know if this works for you

DaveVaval commented 1 month ago

@denisbevilacqua I implemented a function with similar logic using the import { useRunOnJS } from 'react-native-worklets-core'; and it worked! Thanks again!