Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
Sichere ProgrammierungLandlock LSM: Sandbox-Linux ohne Root-Rechte sichern(22.09.2026 um 02:00 Uhr)
Sichere ProgrammierungQuarkus + GraalVM Advanced Obfuscation(22.09.2026 um 02:00 Uhr)
Sichere Programmierung06 — Chat Works. Does the Agent Actually Retrieve Memory?(22.09.2026 um 02:03 Uhr)
Sichere ProgrammierungMCP Debate: Token Tax, Context Bloat, and What Devs Can Do(22.09.2026 um 02:03 Uhr)
Sichere ProgrammierungI gave my AI agent a kill switch tied to its own bank balance(22.09.2026 um 02:08 Uhr)
Sichere ProgrammierungLandlock LSM: Sandbox-Linux ohne Root-Rechte sichern(22.09.2026 um 02:00 Uhr)
Sichere ProgrammierungQuarkus + GraalVM Advanced Obfuscation(22.09.2026 um 02:00 Uhr)
Sichere Programmierung06 — Chat Works. Does the Agent Actually Retrieve Memory?(22.09.2026 um 02:03 Uhr)
Sichere ProgrammierungMCP Debate: Token Tax, Context Bloat, and What Devs Can Do(22.09.2026 um 02:03 Uhr)
Sichere ProgrammierungI gave my AI agent a kill switch tied to its own bank balance(22.09.2026 um 02:08 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Stop Taking Blurry Scans: How I Built Frame Stability Detection for Android with CameraX

Every document scanner app has the same problem: users tap the capture button while their hand is still moving, and the scan comes out blurry. I spent two weeks solving this while building a production Android scanner app (21K lines of…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

Every document scanner app has the same problem: users tap the capture button while their hand is still moving, and the scan comes out blurry.



I spent two weeks solving this while building a production Android scanner app (21K lines of Kotlin). Here's the approach that actually works.






The Problem



CameraX gives you a camera preview, but it has no concept of "is the frame stable enough to capture?" You need to build that yourself.






The Solution: RMS-Based Frame Stability



Instead of complex optical flow or gyroscope fusion, I used a simple but effective approach: compare consecutive frames using Root Mean Square (RMS) difference.




class FrameStabilityAnalyzer : ImageAnalysis.Analyzer {
private var lastFrameBytes: ByteArray? = null
private var isStable = false
private val STABILITY_THRESHOLD = 5.0 // Tune this value

override fun analyze(imageProxy: ImageProxy) {
val currentBytes = imageProxy.planes[0].buffer.toByteArray()

lastFrameBytes?.let { previous ->
val rms = calculateRMS(previous, currentBytes)
isStable = rms < STABILITY_THRESHOLD
}

lastFrameBytes = currentBytes
imageProxy.close()
}

private fun calculateRMS(a: ByteArray, b: ByteArray): Double {
val size = minOf(a.size, b.size)
var sumSquares = 0.0
for (i in 0 until size) {
val diff = (a[i].toInt() and 0xFF) - (b[i].toInt() and 0xFF)
sumSquares += diff * diff
}
return sqrt(sumSquares / size)
}
}









How It Works





  1. Grab the luminance plane from each camera frame (Y plane in YUV)


  2. Compare it to the previous frame pixel by pixel


  3. Calculate the RMS difference -- low values mean the camera isn't moving


  4. Gate the capture button -- only allow capture when isStable == true






The Key Insight



The threshold value (STABILITY_THRESHOLD = 5.0) is critical. Too low and the user can never capture. Too high and you still get blurry scans.



I found 5.0 works well for document scanning where you want sharp text. For general photos, you might go up to 8-10.






Wiring It Up with CameraX






val stabilityAnalyzer = FrameStabilityAnalyzer()

val imageAnalysis = ImageAnalysis.Builder()
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build()
.also { it.setAnalyzer(executor, stabilityAnalyzer) }

// In your UI, observe stabilityAnalyzer.isStable
// Show a green border when stable, red when shaking









Pro Tips





  • Only analyze a downsampled version of the frame for performance. You don't need full resolution to detect motion.


  • Add a debounce -- require 3 consecutive stable frames before allowing capture. This prevents false positives.


  • Show visual feedback -- users need to know WHY the button is grayed out. A subtle "hold steady" indicator works better than nothing.






Results



After implementing this, the percentage of blurry scans in my app dropped by roughly 80%. Users don't even notice the gating -- they naturally hold still for a fraction of a second, and the capture fires automatically.






This is one of those details that separates a good scanner from a great one. If you're building anything with CameraX that involves document capture, frame stability detection is worth the effort.



I'm currently building this as part of a full production scanner app template. If you're interested in skipping the months of work, check out my profile for more details.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Stop Taking Blurry Scans: How I Built Frame Stability Detection for Android with CameraX

Thematisch verwandte Begriffe: Stop, Taking, Blurry, Scans · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-49449 | Joplin is an open source note-taking and to-do application that organise…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick