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.09k forks source link

❓ Detect the QR code frame and main square frame #2394

Closed DevUser0491 closed 9 months ago

DevUser0491 commented 9 months ago

Question

Please, could someone share the example, how to create a CodeScanner with a frame square and blurred background on both iOS and Android? Inside the frame should detect a code with a green frame, as shown in the picture. I know I need to use frameProcessor and corners/bounding values. How to get them?

Screenshot

What I tried

This is my results, but QR code I can scan in any camera position and Frame is with a black background:

Screenshot

packages:

"react-native-vision-camera": "^3.7.1",  
"react-native-worklets-core": "^0.2.4"

I tried create a first frame with SVG:

import { Svg, Defs, Mask, Rect } from 'react-native-svg';
const CameraFrame = () => (
  <Svg height='100%' width='100%'>
    <Defs>
      <Mask height='100%' id='mask' width='100%' x='0' y='0'>
        <Rect fill='#fff' height='100%' width='100%' />
        <Rect fill='black' height='250' width='250' x='18%' y='30%' />
      </Mask>
    </Defs>
    <Rect
      fill='rgba(0, 0, 0, 0.8)'
      height='100%'
      mask='url(#mask)'
      width='100%'
    />
    <Rect
      height='250'
      stroke='#fff'
      strokeWidth='5'
      width='250'
      x='18%'
      y='30%'
    />
  </Svg>
);

Then use in the Scanner Component:

import * as React from 'react';
import { FC, useCallback, useEffect, useRef, useState } from 'react';

import { useIsFocused } from '@react-navigation/native';
import { Alert, AlertButton, Linking, StyleSheet, View } from 'react-native';
import Reanimated from 'react-native-reanimated';
import { Svg, Defs, Mask, Rect } from 'react-native-svg';
import {
  Code,
  useCameraDevice,
  useCodeScanner,
  Camera,
  CameraPermissionStatus,
  useFrameProcessor,
} from 'react-native-vision-camera';

import { useIsForeground } from './hooks/useIsForeground';

const ReanimatedCamera = Reanimated.createAnimatedComponent(Camera);
Reanimated.addWhitelistedNativeProps({
  zoom: true,
});

const VisionCodeScanner: FC = (props): React.ReactElement => {
  const camera = useRef<Camera>(null);
  const [cameraPermissionStatus, setCameraPermissionStatus] =
    useState<CameraPermissionStatus>('not-determined');
  // 1. Use a simple default back camera
  const device = useCameraDevice('back');

  // 2. Only activate Camera when the app is focused and this screen is currently opened
  const isFocused = useIsFocused();
  const isForeground = useIsForeground();
  const isActive = isFocused && isForeground;

  // 3. (Optional) enable a torch setting
  const [torch, setTorch] = useState(false);

  // 4. On code scanned, we show an aler to the user
  const isShowingAlert = useRef(false);

  const onCodeScanned = useCallback((codes: Code[]) => {
    console.log(`Scanned ${codes.length} codes:`, JSON.stringify(codes));
  }, []);

  // 5. Initialize the Code Scanner to scan QR codes and Barcodes
  const codeScanner = useCodeScanner({
    codeTypes: ['qr', 'ean-13'],
    onCodeScanned,
  });

  const requestCameraPermission = useCallback(async () => {
    const permissionStatus = await Camera.getCameraPermissionStatus();

    if (permissionStatus !== 'granted') {
      await Camera.requestCameraPermission();
    }

    setCameraPermissionStatus(permissionStatus);
  }, []);

  useEffect(() => {
    if (cameraPermissionStatus !== 'granted') {
      (async () => {
        await requestCameraPermission();
      })();
    }
  }, [cameraPermissionStatus, requestCameraPermission]);

  const frameProcessor = useFrameProcessor((frame) => {
    'worklet';
    console.log('frame', frame);
  }, []);

  return (
    <View style={styles.container}>
      {device != null && (
        <>
          <ReanimatedCamera
            ref={camera}
            {...props}
            audio={false}
            codeScanner={codeScanner}
            device={device}
            enableZoomGesture
            frameProcessor={frameProcessor}
            isActive={isActive}
            style={StyleSheet.absoluteFill}
            torch={torch ? 'on' : 'off'}
          />

          <View
            style={{
              position: 'absolute',
              top: 0,
              left: 0,
              bottom: 0,
              right: 0,
            }}
          >
            <CameraFrame />
          </View>
        </>
      )}
    </View>
  );
};

export default VisionCodeScanner;

const styles = StyleSheet.create({
  container: {
    flexGrow: 1,
    borderRadius: 20,
    overflow: 'hidden',
    backgroundColor: 'gray',
  },
});

VisionCamera Version

3.7.1

Additional information

mrousavy commented 9 months ago

Hey! I don't think this is a question related to VisionCamera.

Probably better off to ask this in the community discord.

What you're searching for is a good way to style your Camera so that there is a box around the QR code.