React Native Kamera-Integration mit VisionCamera
AI generated
RN
native
React Native · VisionCamera · iOS · Android
React Native Kamera-Integration mit VisionCamera
von der Foto-Aufnahme bis zum nativen Frame Processor Plugin

react-native-camera ist unmaintained, expo-camera ist solide, aber bei echtem Frame-Processing eingeschränkt. VisionCamera löst die Kamera-Integration in React Native über JSI direkt auf dem nativen Thread und gibt synchronen Zugriff auf jeden einzelnen Kameraframe, nicht nur auf fertige Fotos. Dieser Artikel zeigt Schritt für Schritt, wie Kamera, Frame Processors, QR-Code-Scanning und native Plugins zusammenspielen.

19 Min. Lesezeit VisionCamera · Frame Processors · Worklets iOS · Android · Swift · Kotlin

1. Warum VisionCamera die richtige Wahl ist

Wer vor einigen Jahren eine Kamera-Integration in React Native gebaut hat, landete fast automatisch bei react-native-camera. Das Paket ist inzwischen offiziell unmaintained, bekommt keine Updates für neue iOS- und Android-Versionen mehr und verursacht bei aktuellen React-Native-Versionen zunehmend Build-Probleme. Als Ersatz empfiehlt die Community meist expo-camera, das solide grundlegende Foto- und Videofunktionen liefert und gut in den Expo-Workflow integriert ist. Für einfache Anwendungsfälle wie ein Profilbild-Upload ist das oft ausreichend.

Sobald die Anforderungen über reine Foto- und Videoaufnahme hinausgehen, etwa bei Live-Objekterkennung, Gesichtsfilterung oder eigenem Barcode-Scanning, stößt expo-camera an Grenzen, weil es keinen strukturierten Zugriff auf einzelne Kameraframes vor der finalen Enkodierung bietet. Genau hier setzt VisionCamera an: Die Bibliothek nutzt JSI (JavaScript Interface) statt der klassischen asynchronen Bridge und erlaubt damit synchronen, nahezu latenzfreien Zugriff auf jeden Frame direkt aus JavaScript beziehungsweise aus sogenannten Worklets heraus, bevor überhaupt ein Foto oder Video daraus entsteht.

Der Unterschied ist konzeptionell entscheidend: Während react-native-camera und expo-camera die Kamera im Wesentlichen als Blackbox behandeln, aus der am Ende fertige Dateien herauskommen, macht VisionCamera jeden einzelnen Frame zu einem first-class citizen der API. Das ist die Grundlage für alles, was in den folgenden Abschnitten folgt, von der einfachen Foto-Aufnahme bis zu nativen Frame Processor Plugins für rechenintensive Bildverarbeitung. Für eine moderne React Native Kamera-Integration mit Zukunftsperspektive führt an VisionCamera aktuell kaum ein Weg vorbei.

2. Installation und Setup

Der erste Schritt jeder VisionCamera-Integration ist die Installation über npm install react-native-vision-camera, gefolgt von pod install im ios-Verzeichnis, da VisionCamera native Module für iOS und Android mitbringt und kein reines JavaScript-Paket ist. Unter iOS müssen zusätzlich NSCameraUsageDescription und, sofern Videoaufnahme mit Ton geplant ist, NSMicrophoneUsageDescription in der Info.plist eingetragen werden. Fehlen diese Einträge, stürzt die App beim ersten Kamerazugriff kommentarlos ab, ein klassischer Stolperstein bei der Kamera-Integration.

Unter Android müssen die Berechtigungen CAMERA und, analog zu iOS, RECORD_AUDIO in der AndroidManifest.xml deklariert werden. VisionCamera setzt zudem eine minimale Android-SDK-Version voraus, aktuell wird ein minSdkVersion von 26 empfohlen, damit die neueren Camera2-APIs zuverlässig zur Verfügung stehen. Wer ein bestehendes Projekt mit einer niedrigeren minimalen SDK-Version pflegt, muss diese vor der Integration anheben.

Zur Laufzeit reichen die Manifest-Einträge allein nicht aus, da sowohl iOS als auch Android ab einer bestimmten Version eine explizite Nutzer-Zustimmung verlangen. Die statischen Methoden Camera.requestCameraPermission() und Camera.requestMicrophonePermission() zeigen den systemeigenen Berechtigungsdialog an und liefern ein Ergebnis wie granted, denied oder not-determined zurück. Erst nach erfolgreicher Zustimmung liefert der Hook useCameraDevice ein nutzbares Kameragerät, weshalb der Permission-Check immer vor dem Rendern der eigentlichen Camera-Komponente erfolgen sollte.


# Install the VisionCamera package
npm install react-native-vision-camera

# iOS: install native pods (required, not a pure JS package)
cd ios && pod install && cd ..

# Android: no extra native step needed beyond a standard rebuild
npx react-native run-android

# Info.plist entries (ios/YourApp/Info.plist) - add manually
# <key>NSCameraUsageDescription</key>
# <string>This app uses the camera for photo and video capture</string>
# <key>NSMicrophoneUsageDescription</key>
# <string>This app uses the microphone for video recording with audio</string>

# AndroidManifest.xml entries (android/app/src/main/AndroidManifest.xml)
# <uses-permission android:name="android.permission.CAMERA" />
# <uses-permission android:name="android.permission.RECORD_AUDIO" />

3. Die Camera-Komponente und Device-Auswahl

Im Zentrum jeder VisionCamera-basierten Kamera-Integration steht die Camera-Komponente, die ein konkretes Kameragerät als Prop erwartet. Dieses Gerät wird über den Hook useCameraDevice('back') oder useCameraDevice('front') ermittelt, der automatisch das beste verfügbare physische Kameramodul auf dem jeweiligen Gerät auswählt, inklusive Ultra-Weitwinkel- oder Tele-Objektiven auf unterstützten Smartphones. Anders als bei älteren Bibliotheken muss die Geräteauswahl nicht manuell über Plattform-Checks erfolgen.

Für die Auflösung und Framerate ist der Hook useCameraFormat zuständig, der aus den vom Gerät unterstützten Formaten dasjenige auswählt, das am besten zu den übergebenen Anforderungen passt, etwa eine Mindestauflösung von 1920x1080 bei mindestens 30 Bildern pro Sekunde. Diese explizite Format-Auswahl ist wichtig, weil moderne Smartphone-Kameras oft Dutzende Formate mit unterschiedlichen Auflösungen, Framerates und Pixel-Formaten anbieten, und die falsche Wahl entweder unnötig hohe Rechenlast oder eine für den Anwendungsfall zu geringe Bildqualität bedeutet.

Die isActive-Prop der Camera-Komponente ist ein oft unterschätztes, aber zentrales Detail: Wird sie auf false gesetzt, sobald der Nutzer den Kamera-Screen verlässt, etwa beim Navigieren zu einem anderen Tab, pausiert VisionCamera den Kamerasensor vollständig. Das spart spürbar Akku, reduziert die Geräteerwärmung und ist zudem aus Datenschutzsicht relevant, weil die Kamera dann tatsächlich nicht mehr aktiv Bilddaten erfasst, auch wenn die Komponente selbst noch im React-Baum eingehängt bleibt.


// CameraScreen.js — device selection, format, and capture
import { useRef, useState, useCallback } from 'react';
import { View, Pressable, Text, StyleSheet } from 'react-native';
import {
  Camera,
  useCameraDevice,
  useCameraFormat,
  useCameraPermission,
} from 'react-native-vision-camera';
import { useIsFocused } from '@react-navigation/native';

export function CameraScreen() {
  const camera = useRef(null);
  const isFocused = useIsFocused();
  const { hasPermission, requestPermission } = useCameraPermission();
  const [isRecording, setIsRecording] = useState(false);

  const device = useCameraDevice('back');
  const format = useCameraFormat(device, [
    { videoResolution: { width: 1920, height: 1080 } },
    { fps: 30 },
  ]);

  const takePhoto = useCallback(async () => {
    if (!camera.current) return;
    const photo = await camera.current.takePhoto({
      flash: 'auto',
      qualityPrioritization: 'balanced',
    });
    console.log('Photo saved at', photo.path);
  }, []);

  const startRecording = useCallback(() => {
    if (!camera.current) return;
    setIsRecording(true);
    camera.current.startRecording({
      onRecordingFinished: (video) => {
        setIsRecording(false);
        console.log('Video saved at', video.path);
      },
      onRecordingError: (error) => {
        setIsRecording(false);
        console.error('Recording failed', error);
      },
    });
  }, []);

  const stopRecording = useCallback(async () => {
    if (!camera.current) return;
    await camera.current.stopRecording();
  }, []);

  if (!hasPermission) {
    return (
      <Pressable onPress={requestPermission}>
        <Text>Grant camera permission</Text>
      </Pressable>
    );
  }
  if (device == null) return <Text>No camera device found</Text>;

  return (
    <View style={styles.container}>
      <Camera
        ref={camera}
        style={styles.camera}
        device={device}
        format={format}
        isActive={isFocused}
        photo={true}
        video={true}
        audio={true}
      />
      <Pressable onPress={isRecording ? stopRecording : startRecording}>
        <Text>{isRecording ? 'Stop' : 'Record'}</Text>
      </Pressable>
      <Pressable onPress={takePhoto}>
        <Text>Take photo</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1 },
  camera: { flex: 1 },
});

4. Foto- und Videoaufnahme

Die Methode camera.takePhoto() ist der zentrale Einstiegspunkt für Foto-Aufnahmen und akzeptiert Optionen wie flash (on, off, auto) sowie qualityPrioritization, mit dem zwischen schnellerer Aufnahme (speed) und höherer Bildqualität (quality) abgewogen werden kann. Das zurückgegebene Objekt enthält unter anderem path, width, height und Metadaten wie die Orientierung, jedoch keine fertig enkodierte Bilddatei im Speicher, sondern einen Dateipfad auf einen temporären Speicherort.

Für Videoaufnahmen existiert kein einzelner asynchroner Aufruf, sondern das Paar startRecording() und stopRecording(). startRecording() erwartet Callback-Funktionen wie onRecordingFinished und onRecordingError, weil eine Videoaufnahme naturgemäß über einen längeren Zeitraum läuft und ihr Ergebnis nicht als einfaches Promise zurückgegeben werden kann. Innerhalb von onRecordingFinished steht dann, analog zu Fotos, ein Dateipfad zur Verfügung, über den das aufgenommene Video weiterverarbeitet werden kann.

Ein wichtiger praktischer Punkt bei der Kamera-Integration: Sowohl Fotos als auch Videos landen zunächst in einem temporären, app-internen Verzeichnis, das vom Betriebssystem jederzeit bereinigt werden kann. Wer die Aufnahme dauerhaft behalten möchte, etwa für einen späteren Upload oder eine lokale Galerie, muss die Datei aktiv in ein persistentes Verzeichnis verschieben oder umbenennen, üblicherweise mit einer Dateisystem-Bibliothek wie react-native-fs. Wird dieser Schritt vergessen, verschwinden aufgenommene Fotos und Videos nach einem App-Neustart scheinbar spurlos.

5. Frame Processors und Worklets

Der eigentliche Alleinstellungsfaktor von VisionCamera gegenüber klassischen Kamera-Bibliotheken sind Frame Processors, aktiviert über den Hook useFrameProcessor(). Der übergebene Callback wird mit der Direktive 'worklet' markiert, einem Konzept aus der Reanimated-Welt, das den Code zur Compile-Zeit so umbaut, dass er nicht auf dem gewöhnlichen JavaScript-Thread läuft, sondern auf einem eigenen, dedizierten Hintergrund-Thread, direkt über JSI angebunden.

Diese Architekturentscheidung ist entscheidend für Echtzeit-Anwendungen: Ein Kamerasensor liefert häufig 30 oder 60 Frames pro Sekunde, was einem Zeitbudget von 33 beziehungsweise 16 Millisekunden pro Frame entspricht. Würde die Frame-Verarbeitung auf dem regulären JS-Thread laufen, würde sie mit jeder anderen JavaScript-Ausführung konkurrieren, etwa mit UI-Updates oder Netzwerk-Callbacks, und unweigerlich zu Rucklern und verpassten Frames führen. Der separate Worklet-Thread entkoppelt die Frame-Verarbeitung vollständig von der restlichen App-Logik.

Für rechenintensivere Verarbeitung, die nicht bei jedem einzelnen Frame nötig ist, etwa eine Objekterkennung, die auch bei 10 Auswertungen pro Sekunde ausreichend reagiert, bietet VisionCamera die Hilfsfunktion runAtTargetFps(). Sie drosselt gezielt, wie oft der eingeschlossene Code tatsächlich ausgeführt wird, während der Frame Processor selbst weiterhin mit voller Kamerageschwindigkeit aufgerufen wird. Das verhindert, dass teure Berechnungen den Worklet-Thread verstopfen und dadurch indirekt doch wieder die Vorschau ruckeln lassen.


// FrameProcessorScreen.js — worklet-based frame processor with throttling
import { StyleSheet } from 'react-native';
import { useCameraDevice, useFrameProcessor, useCodeScanner } from 'react-native-vision-camera';
import { runAtTargetFps } from 'react-native-vision-camera';
import { Camera } from 'react-native-vision-camera';

export function ScannerScreen() {
  const device = useCameraDevice('back');

  const frameProcessor = useFrameProcessor((frame) => {
    'worklet';
    // Runs on a dedicated background thread via JSI, not the JS thread
    runAtTargetFps(5, () => {
      'worklet';
      // Expensive analysis throttled to 5 evaluations per second
      const brightness = estimateBrightness(frame);
      if (brightness < 40) {
        console.log('Low light detected, consider enabling flash');
      }
    });
  }, []);

  const codeScanner = useCodeScanner({
    codeTypes: ['qr', 'ean-13', 'code-128'],
    onCodeScanned: (codes) => {
      // Runs back on the JS thread — safe to update React state here
      if (codes.length > 0) {
        console.log('Scanned value:', codes[0].value);
      }
    },
  });

  if (device == null) return null;

  return (
    <Camera
      style={styles.camera}
      device={device}
      isActive={true}
      frameProcessor={frameProcessor}
      codeScanner={codeScanner}
    />
  );
}

const styles = StyleSheet.create({
  camera: { flex: 1 },
});

6. Barcode- und QR-Code-Scanning

Für den häufigen Anwendungsfall des Barcode- und QR-Code-Scannings muss kein eigener Frame Processor von Grund auf geschrieben werden, da VisionCamera dafür den fertigen Hook useCodeScanner() mitbringt. Über das Array codeTypes wird festgelegt, welche Formate erkannt werden sollen, etwa qr für QR-Codes, ean-13 für klassische Produkt-Barcodes oder code-128 für Versand- und Ticket-Codes. Die Erkennung selbst läuft intern über die nativen Vision-APIs von iOS und Android und muss nicht manuell implementiert werden.

Der Callback onCodeScanned wird, im Gegensatz zu einem klassischen Frame Processor, wieder auf dem regulären JS-Thread ausgeführt, weshalb dort ohne Einschränkung React-State aktualisiert, navigiert oder ein Netzwerk-Request ausgelöst werden kann. Praktisch bewährt sich dabei, erkannte Codes zusätzlich zu deduplizieren, etwa über einen kurzen Timer oder einen Vergleich mit dem zuletzt gescannten Wert, da derselbe Code sonst innerhalb weniger hundert Millisekunden mehrfach gemeldet wird, solange er im Kamerabild sichtbar bleibt.

Ein typisches Praxisszenario für diese Art der Kamera-Integration ist ein Ticket-Scanner beim Einlass einer Veranstaltung: Die App scannt den QR-Code auf dem digitalen Ticket, gleicht den Wert gegen eine Buchungs-API ab und zeigt sofort visuell an, ob der Einlass gültig ist. Ein weiteres Beispiel ist ein Produkt-Check-in im Lager, bei dem ein EAN-13-Barcode auf einem Paket gescannt und automatisch mit dem passenden Lagerplatz verknüpft wird. In beiden Fällen ersetzt der integrierte Code-Scanner ein separates, oft schwerfälligeres Scanning-Paket vollständig.

7. Performance-Optimierung

Die Wahl des richtigen Kameraformats über useCameraFormat ist der erste und wirkungsvollste Hebel für Performance-Optimierung. Eine 4K-Auflösung mit 60 Bildern pro Sekunde erzeugt eine deutlich größere Datenmenge pro Sekunde als 1080p mit 30 Bildern pro Sekunde, und jeder zusätzliche Frame Processor muss diese Datenmenge verarbeiten. Wer nur einen QR-Code-Scanner benötigt, sollte deshalb bewusst ein niedrigeres, aber ausreichendes Format anfordern, statt reflexartig die höchste verfügbare Auflösung zu wählen.

Ein zweiter wichtiger Hebel ist das pixelFormat der Kamera. VisionCamera unterstützt unter anderem yuv und rgb, wobei yuv das native Format der meisten Kamerasensoren ist und deshalb ohne zusätzliche Konvertierung schneller verarbeitet werden kann. Nur wenn ein Frame Processor tatsächlich RGB-Werte pro Pixel benötigt, etwa für bestimmte Bildfilter, lohnt sich die explizite Anforderung von rgb, da diese Konvertierung selbst wieder Rechenzeit kostet, die bei reiner Code-Erkennung unnötig wäre.

Darüber hinaus lohnt es sich, unnötige Re-Renders der Camera-Komponente zu vermeiden, da jedes Neu-Rendern potenziell den zugrunde liegenden nativen View neu konfiguriert. Frame Processors und der Code Scanner sollten deshalb mit useCallback beziehungsweise den entsprechenden Memoisierungs-Mechanismen der Hooks stabil gehalten werden. Wichtig ist außerdem: Reine JavaScript-basierte Frame Processors stoßen bei wirklich komplexer Bildverarbeitung, etwa neuronalen Netzen für Gesichtserkennung, an eine harte Grenze, weil selbst der schnelle Worklet-Thread nicht die Rohleistung nativer Bildverarbeitungs-Frameworks erreicht. Für solche Fälle sind native Frame Processor Plugins der nächste logische Schritt.

8. Native Frame Processor Plugins

Für rechenintensive Aufgaben wie Gesichtserkennung mit Apples Vision Framework oder Objekterkennung mit Google ML Kit reicht ein reiner JavaScript-Frame-Processor oft nicht aus, selbst wenn er auf dem separaten Worklet-Thread läuft. Die Lösung ist ein natives Frame Processor Plugin, das in Swift beziehungsweise Kotlin geschrieben wird und den nativen Frame-Buffer direkt verarbeitet, ohne den Umweg über eine JavaScript-Repräsentation der Bilddaten zu nehmen.

Aus JavaScript-Sicht wird ein solches Plugin über VisionCameraProxy.initFrameProcessorPlugin() registriert und liefert eine aufrufbare Funktion zurück, die innerhalb eines Frame Processors wie eine ganz normale Funktion verwendet werden kann. Intern greift VisionCamera dabei wieder auf JSI zurück, sodass der Aufruf synchron und ohne die Serialisierungskosten der klassischen Bridge erfolgt. Für die App-Entwicklerin oder den App-Entwickler fühlt sich das native Plugin dadurch fast wie eine gewöhnliche JavaScript-Funktion an, obwohl im Hintergrund nativer Swift- oder Kotlin-Code auf dem Frame arbeitet.

Der Performance-Vorteil eines nativen Plugins liegt darin, dass rechenintensive Operationen wie das Anwenden eines neuronalen Netzes direkt in nativem Code laufen, statt über zusätzliche Zwischenschritte in JavaScript-Objekte konvertiert zu werden. Gerade bei Aufgaben, die für jeden einzelnen Frame in Echtzeit laufen sollen, etwa eine kontinuierliche Gesichtsverfolgung, macht dieser Unterschied den Ausschlag zwischen einer flüssigen und einer spürbar ruckelnden Kamera-Vorschau.


// FaceDetectorPlugin.swift — minimal native Frame Processor Plugin (iOS)
import VisionCamera

@objc(FaceDetectorPlugin)
public class FaceDetectorPlugin: FrameProcessorPlugin {

  public override init(proxy: VisionCameraProxyHolder, options: [AnyHashable: Any]! = [:]) {
    super.init(proxy: proxy, options: options)
  }

  public override func callback(_ frame: Frame, withArguments arguments: [AnyHashable: Any]?) -> Any {
    // Access the underlying CMSampleBuffer for native processing
    let buffer = frame.buffer

    // Run face detection using Apple's Vision framework (simplified)
    let faceCount = detectFaces(in: buffer)

    return ["faceCount": faceCount]
  }
}

// FaceDetectorPlugin.kt — equivalent native Frame Processor Plugin (Android)
package com.mironsoft.app

import com.mrousavy.camera.frameprocessors.Frame
import com.mrousavy.camera.frameprocessors.FrameProcessorPlugin
import com.mrousavy.camera.frameprocessors.VisionCameraProxy

class FaceDetectorPlugin(proxy: VisionCameraProxy, options: Map<String, Any>?) :
  FrameProcessorPlugin() {

  override fun callback(frame: Frame, arguments: Map<String, Any>?): Any {
    // Access the underlying Image for native processing (e.g. via ML Kit)
    val image = frame.image
    val faceCount = detectFaces(image)

    return mapOf("faceCount" to faceCount)
  }
}

9. VisionCamera im Vergleich

Die Entscheidung zwischen den drei gängigen Kamera-Bibliotheken für React Native hängt stark davon ab, wie tief die geplante Kamera-Integration in die Kameradaten eingreifen muss. Die folgende Übersicht fasst die wichtigsten Unterschiede zusammen.

Bibliothek Frame-Processing Wartungsstatus Performance Setup-Komplexität
react-native-camera Nicht vorgesehen Deprecated, unmaintained Bridge-basiert, langsam Gering
expo-camera Eingeschränkt, kein Custom-Frame-Processing Aktiv gepflegt Solide für Standardfälle Sehr gering
react-native-vision-camera Voll unterstützt, JSI-basiert Aktiv gepflegt Nativ, JSI-synchron Mittel

In der Praxis empfiehlt sich expo-camera für einfache Anwendungsfälle ohne Echtzeit-Bildverarbeitung, etwa reine Foto- oder Video-Uploads innerhalb eines Expo-Managed-Workflows. Sobald Frame Processors, QR-Code-Scanning mit eigener Logik oder native Bildverarbeitung Teil der Anforderungen sind, ist VisionCamera die technisch überlegene und zukunftssichere Wahl für die Kamera-Integration in React Native. react-native-camera sollte in neuen Projekten nicht mehr verwendet werden.

Mironsoft

React Native Entwicklung für iOS und Android

Kamera-Integration, die auch bei Echtzeit-Verarbeitung flüssig bleibt?

Wir richten VisionCamera für eure React-Native-App ein, bauen Frame Processors, QR-Code-Scanning und native Plugins in Swift und Kotlin für performante Echtzeit-Bildverarbeitung.

VisionCamera-Setup

Geräteauswahl, Formate, Permissions und Foto-/Videoaufnahme sauber konfiguriert

Frame Processors

Worklet-basierte Echtzeit-Verarbeitung inklusive QR-Code- und Barcode-Scanning

Native Plugins

Swift- und Kotlin-Plugins für Gesichtserkennung und komplexe Bildverarbeitung

10. Zusammenfassung

VisionCamera löst die Kamera-Integration in React Native fundamental anders als der veraltete react-native-camera oder das solide, aber eingeschränkte expo-camera: über JSI und Frame Processors bekommt die App direkten, synchronen Zugriff auf jeden einzelnen Kameraframe, nicht nur auf fertige Fotos und Videos. Die Grundlagen sind schnell aufgesetzt, npm-Installation, native Permissions in Info.plist und AndroidManifest.xml, Geräteauswahl über useCameraDevice und Format-Wahl über useCameraFormat.

Frame Processors mit der 'worklet'-Direktive laufen auf einem eigenen Hintergrund-Thread und ermöglichen Echtzeit-Verarbeitung bei 30 oder 60 Bildern pro Sekunde, ohne den JS-Thread zu blockieren. Der eingebaute useCodeScanner()-Hook deckt Barcode- und QR-Code-Scanning ab, ohne dass eigener Erkennungscode geschrieben werden muss. Für wirklich rechenintensive Aufgaben wie Gesichtserkennung sind native Frame Processor Plugins in Swift und Kotlin der letzte Baustein, der die volle native Performance ausschöpft, ohne die einheitliche JavaScript-Schnittstelle von VisionCamera aufzugeben.

React Native Kamera-Integration mit VisionCamera — Das Wichtigste auf einen Blick

Warum VisionCamera

JSI statt klassischer Bridge, synchroner Zugriff auf jeden Frame statt nur auf fertige Fotos/Videos.

Grundfunktionen

useCameraDevice, useCameraFormat, takePhoto() und startRecording()/stopRecording().

Frame Processors

useFrameProcessor() mit 'worklet'-Direktive läuft auf eigenem Hintergrund-Thread via JSI.

Native Plugins

Swift/Kotlin-Plugins über VisionCameraProxy.initFrameProcessorPlugin() für maximale Performance.

11. FAQ: React Native Kamera-Integration mit VisionCamera

1VisionCamera vs. expo-camera?
expo-camera deckt Standard-Foto/Video ab, aber ohne Frame-Zugriff. VisionCamera nutzt JSI und Frame Processors für synchronen Zugriff auf jeden einzelnen Frame.
2Was ist ein Worklet?
Eine mit 'worklet' markierte Funktion, die auf einem eigenen Hintergrund-Thread läuft, direkt über JSI angebunden, statt auf dem regulären JS-Thread.
3Warum die 'worklet'-Direktive?
Ohne sie liefe der Code auf dem JS-Thread und würde mit UI-Updates konkurrieren. Bei 30 bis 60 Frames pro Sekunde führt das zu Rucklern und verpassten Frames.
4Grenzen bei der Performance?
JS-Frame-Processors reichen bei sehr komplexer Bildverarbeitung wie neuronalen Netzen nicht aus. Native Frame Processor Plugins in Swift oder Kotlin lösen das.
5Welche Permissions sind nötig?
NSCameraUsageDescription/NSMicrophoneUsageDescription unter iOS, CAMERA/RECORD_AUDIO unter Android, jeweils zur Laufzeit per Camera.requestCameraPermission() bestätigt.
6Welche Code-Typen werden unterstützt?
Unter anderem qr, ean-13 und code-128 über das codeTypes-Array, erkannt durch die nativen Vision-APIs von iOS und Android.
7Wie schreibt man ein natives Plugin?
In Swift oder Kotlin, registriert aus JS über VisionCameraProxy.initFrameProcessorPlugin(), synchron aufrufbar innerhalb eines Frame Processors.
8Blitz und Taschenlampe steuern?
Blitz über die flash-Option von takePhoto() (on/off/auto). Dauerhafte Taschenlampe über die torch-Prop der Camera-Komponente.
9Warum ist Format-Auswahl wichtig?
useCameraFormat wählt Auflösung/Framerate. Eine unnötig hohe Auflösung erzeugt mehr Daten pro Frame und damit mehr Rechenlast ohne Mehrwert.
10Warum ist react-native-camera veraltet?
Offiziell unmaintained, keine Updates mehr für neue iOS/Android-Versionen, zunehmend Build-Probleme. VisionCamera ist die aktiv gepflegte Alternative.