{"slug":"mobile-camera-vision-camera","title":"mobile-camera-vision-camera","summary":"VisionCamera v4+ - photo/video capture, QR/barcode scanning, real-time frame processors, zoom/focus/exposure, HDR, location metadata, format selection","platform":"Claude","tags":[],"authorName":"LLM Mart","authorSlug":"llm-mart","score":0,"source":"github","price":null,"verified":false,"createdAt":"2026-09-29T15:28:13.186012Z","repo":{"url":"https://github.com/agents-inc/skills","stars":24,"forks":8,"license":"MIT","updatedAt":"2026-09-07T17:50:55Z"},"bodyHtml":"<hr>\n<h2>name: mobile-camera-vision-camera\ndescription: VisionCamera v4+ - photo/video capture, QR/barcode scanning, real-time frame processors, zoom/focus/exposure, HDR, location metadata, format selection</h2>\n<h1>VisionCamera Patterns</h1>\n<blockquote>\n<p><strong>Quick Guide:</strong> Use VisionCamera for high-performance camera features in React Native. Control the camera lifecycle with <code>isActive</code> (never unmount/remount). Use <code>useCameraDevice</code> to select back/front cameras, <code>useCameraPermission</code> for permissions. Capture photos with <code>takePhoto()</code>, record video with <code>startRecording()</code>/<code>stopRecording()</code>, scan codes with <code>useCodeScanner</code>, and process frames in real time with <code>useFrameProcessor</code> worklets. Frame processors run on a parallel JS thread via JSI -- keep them fast or use <code>runAsync</code>/<code>runAtTargetFps</code> to avoid blocking the pipeline.</p>\n</blockquote>\n<hr>\n<p>&lt;critical_requirements&gt;</p>\n<h2>CRITICAL: Before Using This Skill</h2>\n<blockquote>\n<p><strong>All code must follow project conventions in CLAUDE.md</strong> (kebab-case, named exports, import ordering, <code>import type</code>, named constants)</p>\n</blockquote>\n<p><strong>(You MUST set <code>isActive</code> based on screen focus AND app state -- camera must pause when backgrounded or navigated away)</strong></p>\n<p><strong>(You MUST request permissions before rendering the Camera -- <code>useCameraPermission</code> returns <code>hasPermission</code> and <code>requestPermission</code>)</strong></p>\n<p><strong>(You MUST include the <code>'worklet'</code> directive as the first line of every frame processor function body)</strong></p>\n<p><strong>(You MUST enable only the pipelines you need (<code>photo</code>, <code>video</code>, <code>codeScanner</code>, <code>frameProcessor</code>) -- unused pipelines waste resources)</strong></p>\n<p><strong>(You MUST use <code>useSharedValue</code> (not <code>useState</code>) for data shared between frame processors and the React thread)</strong></p>\n<p>&lt;/critical_requirements&gt;</p>\n<hr>\n<p><strong>Auto-detection:</strong> VisionCamera, react-native-vision-camera, useCameraDevice, useCameraDevices, useCameraPermission, useMicrophonePermission, useCodeScanner, useFrameProcessor, useSkiaFrameProcessor, useCameraFormat, takePhoto, takeSnapshot, startRecording, stopRecording, Camera component, frame processor, worklet, codeScanner, photoQualityBalance, enableLocation, videoHdr, photoHdr</p>\n<p><strong>When to use:</strong></p>\n<ul>\n<li>Capturing photos or recording video in a React Native app</li>\n<li>Scanning QR codes or barcodes (EAN-13, Code-128, etc.)</li>\n<li>Real-time frame processing for ML, object detection, or image analysis</li>\n<li>Implementing zoom, focus, exposure, or HDR controls</li>\n<li>Embedding GPS location metadata in captured media</li>\n<li>Selecting specific camera devices (ultra-wide, telephoto, front/back)</li>\n</ul>\n<p><strong>When NOT to use:</strong></p>\n<ul>\n<li>Picking images from the device gallery (use an image picker)</li>\n<li>Simple static image display (use standard Image component)</li>\n<li>Web-only camera access (use browser MediaDevices API)</li>\n</ul>\n<p><strong>Key patterns covered:</strong></p>\n<ul>\n<li>Camera lifecycle management with <code>isActive</code> and screen/app state</li>\n<li>Permission handling with hooks (<code>useCameraPermission</code>, <code>useMicrophonePermission</code>)</li>\n<li>Photo capture (<code>takePhoto</code>, <code>takeSnapshot</code>) and video recording</li>\n<li>QR/barcode scanning with <code>useCodeScanner</code></li>\n<li>Frame processors with worklets, <code>runAsync</code>, and <code>runAtTargetFps</code></li>\n<li>Device selection, format selection, zoom, focus, exposure, HDR</li>\n<li>Location metadata embedding</li>\n<li>Performance optimization (pipeline selection, buffer compression, pixel format)</li>\n</ul>\n<p><strong>Detailed Resources:</strong></p>\n<ul>\n<li><a href=\"examples/core.md\">examples/core.md</a> - Camera setup, permissions, lifecycle, photo capture, video recording</li>\n<li><a href=\"examples/scanning-and-processing.md\">examples/scanning-and-processing.md</a> - Code scanning, frame processors, worklet patterns</li>\n<li><a href=\"reference.md\">reference.md</a> - Decision frameworks, device/format selection, performance checklist</li>\n</ul>\n<hr>\n\n<hr>\n\n<hr>\n<p>&lt;decision_framework&gt;</p>\n<h2>Decision Framework</h2>\n<h3>Capture Method</h3>\n<pre><code>What do you need to capture?\n|\n+-&gt; Still image?\n|   +-&gt; High quality (AE/AF/AWB) → takePhoto()\n|   +-&gt; Fast preview capture (~16ms) → takeSnapshot() (requires video pipeline)\n|\n+-&gt; Video?\n|   +-&gt; Continuous recording → startRecording() / stopRecording()\n|   +-&gt; Need pause/resume → pauseRecording() / resumeRecording()\n|   +-&gt; User cancelled → cancelRecording()\n|\n+-&gt; QR/barcode scanning?\n|   +-&gt; useCodeScanner (native thread, no frame processor needed)\n|\n+-&gt; Real-time frame analysis (ML, detection)?\n    +-&gt; useFrameProcessor with native plugins\n    +-&gt; Need Skia drawing on frames? → useSkiaFrameProcessor\n</code></pre>\n<h3>Frame Processor Scheduling</h3>\n<pre><code>How fast must your processor run?\n|\n+-&gt; Every frame (30/60 FPS)?\n|   +-&gt; Processing &lt; 33ms? → Default synchronous processor\n|   +-&gt; Processing &gt; 33ms? → runAsync (offload to separate thread)\n|\n+-&gt; Lower rate is fine (5-10 FPS)?\n    +-&gt; runAtTargetFps(targetFps, () =&gt; { ... })\n</code></pre>\n<h3>Device Selection</h3>\n<pre><code>Which camera?\n|\n+-&gt; Simple back/front → useCameraDevice(\"back\") or useCameraDevice(\"front\")\n+-&gt; Multi-lens (0.5x + 1x + 3x) → useCameraDevice(\"back\", { physicalDevices: [...] })\n+-&gt; External USB camera → Filter useCameraDevices() for position === \"external\"\n+-&gt; Custom logic → useCameraDevices() + useMemo with your own filter\n</code></pre>\n<p>&lt;/decision_framework&gt;</p>\n<hr>\n<p>&lt;red_flags&gt;</p>\n<h2>RED FLAGS</h2>\n<p><strong>High Priority Issues:</strong></p>\n<ul>\n<li>Mounting/unmounting Camera instead of toggling <code>isActive</code> -- wastes resources, slow resume</li>\n<li>Missing <code>'worklet'</code> directive in frame processor function -- silently runs on wrong thread, crashes</li>\n<li>Using <code>useState</code> to share data from frame processors -- causes thread context switching, use <code>useSharedValue</code></li>\n<li>Enabling all pipelines (<code>photo</code>, <code>video</code>, <code>codeScanner</code>, frame processor) when only one is needed -- wastes memory and battery</li>\n<li>Not requesting permissions before rendering Camera -- causes crash or blank preview</li>\n<li>Calling <code>camera.current.takePhoto()</code> before <code>onInitialized</code> fires -- method not ready, throws error</li>\n</ul>\n<p><strong>Medium Priority Issues:</strong></p>\n<ul>\n<li>Capturing 4K when 1080p is sufficient -- wastes memory, slower processing</li>\n<li>Not debouncing <code>onCodeScanned</code> -- fires many times per second, causes excessive state updates</li>\n<li>Using <code>useSkiaFrameProcessor</code> when <code>useFrameProcessor</code> suffices -- Skia adds overhead</li>\n<li>Enabling <code>videoHdr</code> without checking <code>format.supportsVideoHdr</code> -- crashes on unsupported formats</li>\n<li>Not checking <code>device.supportsFocus</code> before calling <code>focus()</code> -- fails on devices without AF</li>\n</ul>\n<p><strong>Gotchas &amp; Edge Cases:</strong></p>\n<ul>\n<li>Zoom is <strong>logarithmic</strong> -- 1x to 2x is a much bigger visual change than 127x to 128x. Use <code>interpolate()</code> for linear gesture mapping.</li>\n<li><code>takeSnapshot()</code> requires <code>video={true}</code> on iOS -- it captures from the video preview buffer</li>\n<li>Frame processors at 4K process ~12MB per frame -- use lower resolution if possible</li>\n<li><code>device.neutralZoom</code> may not be 1.0 on ultra-wide cameras -- always use it as the starting zoom</li>\n<li>Android code scanner requires MLKit (<code>VisionCamera_enableCodeScanner=true</code>) -- without it, scanning silently does nothing</li>\n<li>UPC-A codes report as EAN-13 on iOS (EAN-13 is a superset)</li>\n<li><code>cancelRecording()</code> fires <code>onRecordingError</code> with <code>capture/recording-canceled</code> -- handle this error type gracefully</li>\n<li><code>enableLocation</code> requires platform manifest entries (iOS: <code>NSLocationWhenInUseUsageDescription</code>, Android: <code>ACCESS_FINE_LOCATION</code>)</li>\n<li>Disable location APIs entirely via build flag if unused -- prevents App Store rejection for unnecessary privacy APIs</li>\n<li><code>exposure</code> prop is an offset from auto-exposure, not an absolute ISO value</li>\n<li>Video HDR uses 10-bit pixel format which adds processing overhead -- disable when not needed</li>\n</ul>\n<p>&lt;/red_flags&gt;</p>\n<hr>\n<p>&lt;critical_reminders&gt;</p>\n<h2>CRITICAL REMINDERS</h2>\n<blockquote>\n<p><strong>All code must follow project conventions in CLAUDE.md</strong></p>\n</blockquote>\n<p><strong>(You MUST set <code>isActive</code> based on screen focus AND app state -- camera must pause when backgrounded or navigated away)</strong></p>\n<p><strong>(You MUST request permissions before rendering the Camera -- <code>useCameraPermission</code> returns <code>hasPermission</code> and <code>requestPermission</code>)</strong></p>\n<p><strong>(You MUST include the <code>'worklet'</code> directive as the first line of every frame processor function body)</strong></p>\n<p><strong>(You MUST enable only the pipelines you need (<code>photo</code>, <code>video</code>, <code>codeScanner</code>, <code>frameProcessor</code>) -- unused pipelines waste resources)</strong></p>\n<p><strong>(You MUST use <code>useSharedValue</code> (not <code>useState</code>) for data shared between frame processors and the React thread)</strong></p>\n<p><strong>Failure to follow these rules will cause crashes, blank previews, wasted battery, and dropped frames.</strong></p>\n<p>&lt;/critical_reminders&gt;</p>\n","files":[{"path":"examples/core.md","sizeBytes":10743,"isText":true},{"path":"examples/scanning-and-processing.md","sizeBytes":9260,"isText":true},{"path":"reference.md","sizeBytes":10541,"isText":true},{"path":"SKILL.md","sizeBytes":17334,"isText":true}],"reviewScore":null,"reviewSummary":null,"trust":{"provenance":"trusted-source-unreviewed","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow.","bodySource":null},"bodyLocked":false,"purchaseUrl":null,"sourceUrl":null,"report":{"provenance":"trusted-source-unreviewed","screen":{"ran":true,"outcome":"clean","suspicious":0,"notes":0,"hiddenCharacters":false},"virusScan":{"engine":"clamav","status":"clean","scannedAt":"2026-09-29T15:30:58.709244Z","sha256":"7AFD79F836336108DCCD67AAC05F1D0DD42B5EAFECFE82A94E634E6F792D2228","sizeBytes":16333},"review":null,"source":{"repositoryUrl":"https://github.com/agents-inc/skills","path":"dist/plugins/mobile-camera-vision-camera/skills/mobile-camera-vision-camera","license":"MIT","commit":"3a51ef571e996b18294bf776d53dbdad26de0617","subtreeSha":"672D4D00D13462C1DDAF446EDF17D6D21F12D731D9801EB39AD54545C48AF277","lastSyncedAt":"2026-09-29T15:27:48.914434Z"},"reviewedAt":"2026-09-29T15:36:47.331991Z","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow."},"install":[{"target":"skills-cli","command":"npx skills add https://github.com/agents-inc/skills/tree/main/dist/plugins/mobile-camera-vision-camera/skills/mobile-camera-vision-camera"},{"target":"claude-code","command":"claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install agents-inc-skills@llmmart"},{"target":"git","command":"git clone https://github.com/agents-inc/skills.git"}]}