Untitled

 avatar
unknown
jsx
5 months ago
6.6 kB
1
Indexable
import React, {useEffect, useRef, useState} from 'react';
import {Alert, Modal, SafeAreaView, View, StyleSheet} from 'react-native';

// @ts-ignore
import { createPicture, Skia, SkiaPictureView, useDrawCallback, PaintStyle  } from '@shopify/react-native-skia';
import { useTextRecognition } from 'react-native-vision-camera-text-recognition';
// import { useSharedValue  } from 'react-native-reanimated';

import {RNHoleView} from 'react-native-hole-view';
import {
  Camera,
  useCameraDevice,
  CameraRuntimeError,
  useFrameProcessor,
  useSkiaFrameProcessor,
  DrawableFrame,
  useCameraFormat,
  runAsync,
} from 'react-native-vision-camera';
import {useIsFocused} from '@react-navigation/native';

import {getWindowHeight, getWindowWidth, isIos} from '@/helpers';
import {useAppStateListener} from '@/hooks/useAppStateListener';
import {ICameraScannerProps} from '@/types';
import { Worklets, useSharedValue } from 'react-native-worklets-core';



export const CameraOcr4 = ({
  setIsCameraShown,
  onReadCode,
}: ICameraScannerProps) => {
  const device = useCameraDevice('back');
  const camera = useRef<Camera>(null);
  const isFocused = useIsFocused();
  const [isCameraInitialized, setIsCameraInitialized] = useState(isIos);
  const [isActive, setIsActive] = useState(isIos);
  const [flash, setFlash] = useState<'on' | 'off'>(isIos ? 'off' : 'on');
  const {appState} = useAppStateListener();

  const options = { language : 'latin' } as const
  const {scanText: scanTextBroken} = useTextRecognition(options)
  const scanText = (frame: any) => {
    'worklet'
    return scanTextBroken(frame)
  }
  const progress = useSharedValue<{ x: number; y: number; width: number; height: number } | null>(null)

  // const onTextDetected = Worklets.createRunOnJS((text: any) => {
  //   progress.value = {
  //     x: text.blockCornerPoints[0].x, 
  //     y: text.blockCornerPoints[0].y, 
  //     width: text.blockFrame.width, 
  //     height: text.blockFrame.height
  //   }  
  // })

  // const reactDraw = createPicture((canvas) => {
  //   const text = progress.value || { x: 0, y: 0, width: 0, height: 0 }
  //   console.log(text)
  //   const rect = Skia.XYWHRect(
  //     text.x,
  //     text.y,
  //     text.width * 2,
  //     text.height
  //   );
  //   // @ts-ignore
  //   const paint = Skia.Paint();
  //   // @ts-ignore
  //   paint.setColor(Skia.Color('red'));
  //   // @ts-ignore
  //   // paint.setStyle(paint.Stroke);
  //   // paint.setStrokeWidth(5);

  //   // @ts-ignore
  //   canvas.drawRect(rect, paint);

  // });


  const frameProcessor = useSkiaFrameProcessor((frame) => {
    'worklet'

    runAsync(frame, () => {
      'worklet'
      // console.log("I'm running asynchronously, possibly at a lower FPS rate!")
      const texts = scanText(frame) as any
      if (texts && Array.isArray(texts.blocks) && texts.blocks.length > 0) {
        for (const text of texts.blocks) {
          if (text.blockText === 'Tim') {
            // onTextDetected(text)
            progress.value = {
              x: text.blockCornerPoints[0].x, 
              y: text.blockCornerPoints[0].y, 
              width: text.blockFrame.width, 
              height: text.blockFrame.height
            }
          }
        }
      }
    })


    frame.render()


    function draw(text: any, frame: DrawableFrame) {
      const rect = Skia.XYWHRect(
        text.x,
        text.y - (text.width),
        text.height,
        text.width * 2,

      );
      // @ts-ignore
      const paint = Skia.Paint();
      paint.setColor(Skia.Color('red'));
      paint.setStyle(PaintStyle.Stroke);
      paint.setStrokeWidth(2);
      
      frame.drawRect(rect, paint);
      // @ts-ignore
    }

    progress.value && draw(progress.value, frame);
  }, [])

  useEffect(() => {
    let timeout: NodeJS.Timeout;

    if (isCameraInitialized) {
      timeout = setTimeout(() => {
        setIsActive(true);
        setFlash('off');
      }, 1000);
    }
    setIsActive(false);
    return () => {
      clearTimeout(timeout);
    };
  }, [isCameraInitialized]);

  const onInitialized = () => {
    setIsCameraInitialized(true);
  };

  const onCrossClick = () => {
    setIsCameraShown(false);
  };

  const onError = (error: CameraRuntimeError) => {
    Alert.alert('Error!', error.message);
  };

  if (device == null) {
    Alert.alert('Error!', 'Camera could not be started');
  }

  const [rect, setRect] = useState(Skia.XYWHRect(0, 0, 100, 100));

  if (isFocused && device) {
    return (
      <SafeAreaView style={styles.safeArea}>
        <Modal presentationStyle="fullScreen" animationType="slide">
          <View style={[styles.cameraControls, {backgroundColor: undefined}]} />
          <Camera
            // format={format}
            frameProcessor={frameProcessor}
            torch={flash}
            onInitialized={onInitialized}
            ref={camera}
            onError={onError}
            photo={false}
            style={styles.fullScreenCamera}
            device={device}
            isActive={
              isActive &&
              isFocused &&
              appState === 'active' &&
              isCameraInitialized
            }
          />
          {/* 
            // const format = useCameraFormat(device, [
            //   { fps: 40}, {videoHdr: false } 
            // ])
          <SkiaPictureView picture={reactDraw} />
          <SkiaPictureView
                onLayout={ev => {
                    const layout = ev.nativeEvent.layout;
                    setRect(Skia.XYWHRect(0, 0, layout.width, layout.height));
                }}
                style={StyleSheet.absoluteFill}
                pointerEvents='none'
                mode='continuous'
                picture={reactDraw}
            /> */}
        </Modal>
      </SafeAreaView>
    );
  }
};

export const styles = StyleSheet.create({
  safeArea: {
    position: 'absolute',
    width: '100%',
    height: '100%',
  },
  camera: {
    width: '100%',
    height: 200,
  },
  fullScreenCamera: {
    position: 'absolute',
    width: '100%',
    height: '100%',
    flex: 1,
    zIndex: 100,
  },
  rnholeView: {
    alignSelf: 'center',
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'rgba(0,0,0,0.5)',
  },
  cameraControls: {
    height: '10%',
    top: 15,
    position: 'absolute',
    flexDirection: 'row',
    width: '100%',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingHorizontal: 24,
    zIndex: 1000,
  },
  icon: {
    height: 45,
    width: 45,
    borderRadius: 45,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Editor is loading...
Leave a Comment