From c311d48ec387fee177c4a0a9ab72f4c570cc0691 Mon Sep 17 00:00:00 2001 From: Bartosz Hanc Date: Mon, 22 Jun 2026 04:03:57 +0200 Subject: [PATCH 1/9] chore: clean up and unify example app layout, styling, and dependencies --- .cspell-wordlist.txt | 1 + apps/computer-vision/app/_layout.tsx | 7 + .../app/classification/index.tsx | 315 +++----- apps/computer-vision/app/index.tsx | 3 + apps/computer-vision/app/inspect/index.tsx | 195 +++-- apps/computer-vision/commonStyles.ts | 32 + apps/computer-vision/components/Button.tsx | 102 +++ .../components/ImageViewport.tsx | 91 +++ .../components/LatencyIndicator.tsx | 34 + .../components/ModelStatus.tsx | 69 ++ .../{ => components}/ScreenWrapper.tsx | 0 apps/computer-vision/package.json | 13 +- apps/computer-vision/theme.ts | 41 + apps/computer-vision/utils.ts | 79 +- package.json | 8 +- packages/react-native-executorch/package.json | 5 +- patches/react-native-worklets+0.9.1.patch | 748 ++++++++++++++++++ yarn.lock | 359 +++++++-- 18 files changed, 1679 insertions(+), 423 deletions(-) create mode 100644 apps/computer-vision/commonStyles.ts create mode 100644 apps/computer-vision/components/Button.tsx create mode 100644 apps/computer-vision/components/ImageViewport.tsx create mode 100644 apps/computer-vision/components/LatencyIndicator.tsx create mode 100644 apps/computer-vision/components/ModelStatus.tsx rename apps/computer-vision/{ => components}/ScreenWrapper.tsx (100%) create mode 100644 apps/computer-vision/theme.ts create mode 100644 patches/react-native-worklets+0.9.1.patch diff --git a/.cspell-wordlist.txt b/.cspell-wordlist.txt index fd8fb360b5..fef84a8a24 100644 --- a/.cspell-wordlist.txt +++ b/.cspell-wordlist.txt @@ -229,3 +229,4 @@ imgproc c10 probas Probas +Skia diff --git a/apps/computer-vision/app/_layout.tsx b/apps/computer-vision/app/_layout.tsx index f5506bd40c..4c06fe72a7 100644 --- a/apps/computer-vision/app/_layout.tsx +++ b/apps/computer-vision/app/_layout.tsx @@ -27,6 +27,13 @@ export default function Layout() { title: 'Classification', }} /> + (MODEL_OPTIONS[0].value); - const [imageUri, setImageUri] = useState(null); - const [loading, setLoading] = useState(false); + const [skiaImage, setSkiaImage] = useState(null); + const [isProcessing, setIsProcessing] = useState(false); const [results, setResults] = useState<{ label: string; confidence: number }[]>([]); const [latency, setLatency] = useState(null); const [error, setError] = useState(null); @@ -66,7 +47,8 @@ export default function ClassificationScreen() { const handlePickImage = async (useCamera: boolean) => { const asset = await getImage(useCamera); if (asset?.uri) { - setImageUri(asset.uri); + const img = await loadSkImage(asset.uri); + setSkiaImage(img); setResults([]); setLatency(null); setError(null); @@ -74,218 +56,111 @@ export default function ClassificationScreen() { }; const runClassification = async (sync: boolean) => { - if (!imageUri || !classify || !classifyWorklet) return; - if (!sync) setLoading(true); + if (!skiaImage || !classify || !classifyWorklet) return; + if (!sync) setIsProcessing(true); setError(null); try { - const inputBuffer = await loadImageBuffer(imageUri); + const buffer = { + data: skiaImage.readPixels() as Uint8Array, + width: skiaImage.width(), + height: skiaImage.height(), + format: 'rgba' as const, + layout: 'hwc' as const, + }; const start = Date.now(); const output = sync - ? classifyWorklet(inputBuffer, { topk: 5 }) - : await classify(inputBuffer, { topk: 5 }); + ? classifyWorklet(buffer, { topk: 5 }) + : await classify(buffer, { topk: 5 }); + setLatency(Date.now() - start); setResults(output); } catch (e: any) { setError(e.message || String(e)); } finally { - if (!sync) setLoading(false); + if (!sync) setIsProcessing(false); } }; const activeError = loadError ? String(loadError) : error; return ( - - - Image Classification - - { - setSelectedModel(model); - setResults([]); - setLatency(null); - setError(null); - }} + + + Upload or capture an image to identify objects using an EfficientNet classifier. + + + { + setSelectedModel(model); + setResults([]); + setLatency(null); + setError(null); + }} + /> + + + + handlePickImage(false)} /> + + +