Frame buffers beat photos

The first version of the Lorcana scanner had a shutter button. You lined up a card, tapped, waited, got a result. About three seconds a card, and your thumb hurt after a playset.

The second version never captures a photo at all.

Read the buffer, skip the capture

Recognition runs on whatever is already flowing through the capture pipeline:

func captureOutput(_ output: AVCaptureOutput,
                   didOutput sampleBuffer: CMSampleBuffer,
                   from connection: AVCaptureConnection) {
    guard let pixels = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
    recognizer.submit(pixels)   // no still capture, no pipeline flush
}

The whole speed win comes from deleting the capture step:

  • A still capture reconfigures the camera, which costs a pipeline flush and a couple of hundred milliseconds you can feel.
  • The buffer is already there at sixty frames a second.
  • You were throwing it away to take a worse version of the same image.

Any single frame is a bad frame

Motion blur, glare off the sleeve, a thumb over the set symbol. The fix is to never trust one frame:

Debounce on agreement, not on time. Three frames that say the same thing beat one frame that says it confidently.

Which you should have been doing anyway, shutter or not.


Why the card scanner never takes a picture.

2026-05-02


On this page: