Repository navigation
iOS: scan dense codes at 1080p, from raw frames, with close-range focus - #6159
shai-almog wants to merge 1 commit into
Conversation
Dense PDF417 codes were hard to read on iPhones while Android read them easily. Three causes in the iOS camera, none of them new: - A session opened with no preview size (every Vision scanner) ran at 640x480. It now gets 1080p, falling back to 720p. - Frames were always re-encoded as JPEG at quality 0.8, whatever format the listener asked for. A raw request now gets the pixels as RGBA8888 (iOS has no NV21), which Apple Vision already accepts; the JPEG is encoded lazily only if asked for. - Nothing configured focus for close range, and recent iPhone Pro main cameras cannot focus closer than ~20cm. While frames are delivered the camera now uses continuous near-range autofocus and zooms to the lens' minimum focus distance (Apple's AVCamBarcode formula); the application's zoom and focus mode are put back when delivery stops. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cloudflare Preview
|
|
Developer Guide build artifacts are available for download from this workflow run:
Developer Guide quality checks: |
✅ Continuous Quality ReportTest & Coverage
Static Analysis
Generated automatically by the PR CI workflow. |
|
Compared 195 screenshots: 195 matched. Native Android coverage
✅ Native Android screenshot tests passed. Native Android coverage
Benchmark ResultsDetailed Performance Metrics
|
|
Compared 231 screenshots: 231 matched. |
|
Compared 210 screenshots: 210 matched. Benchmark ResultsDetailed Performance Metrics
ParparVM vs HotSpot (JDK 25): Windows x64Runner CPU: Intel64 Family 6 Model 207 Stepping 2, GenuineIntel (baseline 1 improvement past the baseline (not a failure; rebaseline to lock it in):
Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in
A change that moves performance ON PURPOSE records the new baseline in Result: no regression (improved past the baseline: consider rebaselining) |
|
Compared 210 screenshots: 210 matched. Benchmark ResultsDetailed Performance Metrics
ParparVM vs HotSpot (JDK 25): Windows arm64Runner CPU: ARMv8 (64-bit) Family 8 Model D49 Revision 0, MICROSOFT CORPORATION (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in
Result: no regression |
|
Compared 210 screenshots: 210 matched. ParparVM vs HotSpot (JDK 25): Linux x64Runner CPU: AMD EPYC 9V74 80-Core Processor (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in
Result: no regression |
|
Compared 210 screenshots: 210 matched. ParparVM vs HotSpot (JDK 25): Linux arm64Runner CPU: Neoverse-N2 (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in
Result: no regression |
|
Compared 196 screenshots: 196 matched. Benchmark Results
Detailed Performance Metrics
ParparVM vs HotSpot (JDK 25): macOS arm64Runner CPU: Apple M1 (Virtual) (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 20% (time) / 25% (RAM) above its baseline in
Result: no regression |
|
Compared 193 screenshots: 193 matched. Benchmark Results
Build and Run Timing
Detailed Performance Metrics
|

Dense PDF417 codes were hard to scan on iPhone while Android read them easily. The iOS camera path had three weaknesses:
getJpegBytes()encodes lazily on first call. The native RGBA buffer is reused for the life of the session.CameraFrame.getRawBytes()now documents that a port may answer a raw request in a different raw format, so callers should readgetFormat()first.Still needs a check on a physical recent iPhone: the simulator has no camera.
🤖 Generated with Claude Code