Fotoaparát v mobilních aplikacích — hardwarový modul zařízení přístupný vývojáři prostřednictvím systémových API pro zachycování snímků a videa. Podle Google Android Developers (2025) se CameraX používá ve více než 85% aplikací pro Android vyžadujících práci s fotoaparátem. AVFoundation na iOS a CameraX na Androidu poskytují vysoce úrovňová rozhraní skrývající složitost správy hardwaru.
Hlavní body
Mobilní fotoaparát — vestavěný optický modul sestávající z objektivu, matice (senzoru) a procesoru pro zpracování obrazu (ISP). Vývojář získává přístup k fotoaparátu prostřednictvím operačního systému pomocí speciálních frameworků. Na Androidu jsou to Camera2 API (nízkoúrovňové) a CameraX (vysokoúrovňové založené na Camera2), na iOS — AVFoundation a UIKit pro jednoduché scénáře. Každá platforma poskytuje vlastní sadu nástrojů, ale obecný koncept je stejný: aplikace inicializuje relaci snímání, nakonfiguruje parametry (rozlišení, zaostření, expozice) a přijímá proud snímků nebo jednotlivé obrázky.
Moderní mobilní fotoaparáty podporují mnoho režimů fotografování: HDR, noční režim, portrét s rozmazáním pozadí, zpomalené video a záznam ve formátu RAW. Pro vývojáře jsou k dispozici softwarová nastavení: ISO (citlivost matice), čas expozice, vyvážení bílé, zaostření (automatické a manuální) a stabilizace obrazu. Na vlajkových zařízeních je k dispozici až 4 fotoaparátů s různými ohniskovými vzdálenostmi a aplikace může vybrat konkrétní fotoaparát podle ID.
Na mobilních platformách existuje několik API pro práci s fotoaparátem, lišících se úrovní abstrakce a funkčností. Výběr konkrétního API závisí na požadavcích projektu: pro jednoduché pořizování fotek stačí CameraX nebo UIImagePickerController, pro profesionální aplikace je potřeba Camera2 nebo AVFoundation s přímým ovládáním senzoru. Níže je uvedeno srovnání hlavních API.
| API | Platforma | Úroveň | Vlastnosti |
|---|---|---|---|
| CameraX | Android | Vysoká | Lifecycle-aware, 95% zařízení |
| Camera2 | Android | Nízká | Plná kontrola, RAW, Burst |
| AVFoundation | iOS | Střední | Plná kontrola snímání |
| UIKit (UIImagePickerController) | iOS | Vysoká | Hotové UI, bez přizpůsobení |
CameraX — optimální volba pro většinu aplikací pro Android, které potřebují fotoaparát bez hlubokého přizpůsobení. Knihovna automaticky spravuje životní cyklus Activity a Fragment, podporuje oprávnění a kompatibilitu s různými verzemi Androidu. CameraX díky vrstvě kompatibility zaručuje stejné chování na 95% zařízení Android. Pokud je potřeba náhled fotoaparátu (Preview), pořízení fotky (ImageCapture) nebo analýza streamu (ImageAnalysis) — CameraX zvládá všechny tři scénáře bez psaní složitého kódu.
Camera2 — nízkoúrovňové API pro profesionální scénáře: záznam RAW, ruční nastavení expozice, sériové snímání (burst), současné ovládání více fotoaparátů. Camera2 vyžaduje od vývojáře hluboké pochopení pipeline snímání obrazu, správy StateMachine a zpracování callbacků. Používejte Camera2 pouze pokud CameraX nepokrývá požadavky: například pro aplikace skenování dokumentů s ručním zaostřením nebo vlastní fotoaparáty s nestandardním rozlišením.
Přístup k fotoaparátu vyžaduje výslovný souhlas uživatele na obou platformách. Na Androidu se přidává oprávnění CAMERA do manifestu a od Androidu 6.0 je také nutné žádat o oprávnění za běhu prostřednictvím ActivityCompat.requestPermissions. Na iOS se přidává klíč NSCameraUsageDescription do Info.plist s popisem důvodu použití fotoaparátu. Bez tohoto popisu aplikace havaruje při pokusu o přístup k fotoaparátu. Od iOS 14 se v dialogu oprávnění zobrazuje nejen název aplikace, ale také uvedený důvod — formulace by měla být pro uživatele srozumitelná.
CameraX zjednodušuje práci s fotoaparátem na několik řádků kódu. Pro spuštění náhledu je třeba vytvořit instanci Preview, připojit ji k LifecycleOwner a získat SurfaceProvider pro zobrazení. Pro pořizování fotek se používá ImageCapture s cílem uložení. Níže je uveden úplný příklad spuštění fotoaparátu a pořízení fotky pomocí CameraX v Kotlinu.
val preview = Preview.Builder()
.build()
.also {
it.surfaceProvider = viewFinder.surfaceProvider
}
val imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.build()
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener(Runnable {
val cameraProvider = cameraProviderFuture.get()
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
try {
cameraProvider.unbindAll()
cameraProvider.bindToLifecycle(
this, cameraSelector, preview, imageCapture
)
} catch (e: Exception) {
Log.e("CameraX", "Vazba selhala", e)
}
}, ContextCompact.getMainExecutor(this))
Metoda bindToLifecycle připojuje fotoaparát k životnímu cyklu Activity — při otočení obrazovky nebo přechodu do pozadí se fotoaparát automaticky uvolní. CameraSelector.DEFAULT_BACK_CAMERA vybírá zadní fotoaparát, pro přední se používá DEFAULT_FRONT_CAMERA. Po připojení začne Preview zobrazovat obraz z fotoaparátu v PreviewView a uživatel vidí obraz z fotoaparátu na obrazovce.
val photoFile = File(
externalMediaDirs.firstOrNull(),
"IMG_${System.currentTimeMillis()}.jpg"
)
val outputOptions = ImageCapture.OutputFileOptions
.Builder(photoFile)
.build()
imageCapture.takePicture(
outputOptions,
ContextCompact.getMainExecutor(this),
object : ImageCapture.OnImageSavedCallback {
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
Log.d("CameraX", "Photo saved: ${photoFile.absolutePath}")
}
override fun onError(exception: ImageCaptureException) {
Log.e("CameraX", "Chyba snímání", exception)
}
}
)
Metoda takePicture provádí zachycení snímku z fotoaparátu a ukládá jej do souboru. OutputFileOptions podporuje ukládání do File, ContentResolver a MediaStore. V callbacku onImageSaved aplikace obdrží oznámení o úspěšném uložení a může aktualizovat UI. CAPTURE_MODE_MINIMIZE_LATENCY zajišťuje maximální rychlost závěrky snížením následného zpracování.
Na iOS poskytuje přístup k fotoaparátu framework AVFoundation prostřednictvím třídy AVCaptureSession. Vývojář vytvoří relaci snímání, přidá potřebné vstupy (AVCaptureDeviceInput) a výstupy (AVCapturePhotoOutput, AVCaptureVideoDataOutput) a spustí relaci. Pro zobrazení náhledu se používá AVCaptureVideoPreviewLayer. Níže je uveden příklad konfigurace relace pro pořízení fotky ve Swiftu.
import AVFoundation
let captureSession = AVCaptureSession()
captureSession.sessionPreset = .photo
guard let camera = AVCaptureDevice.default(
for: .video
) else { return }
guard let input = try? AVCaptureDeviceInput(device: camera)
else { return }
let output = AVCapturePhotoOutput()
captureSession.addInput(input)
captureSession.addOutput(output)
DispatchQueue.global(qos: .userInitiated).async {
captureSession.startRunning()
}
AVCaptureSessionPreset.photo nastavuje optimální rozlišení pro fotku (obvykle 12 MP na moderních zařízeních). Vstupem je AVCaptureDeviceInput vytvořený pro fotoaparát zařízení. Po přidání vstupu a výstupu je relace spuštěna v podkladovém vlákně pomocí startRunning — spuštění relace může na starších zařízeních trvat až 200 ms. Pro pořízení fotky se volá capturePhoto(with:delegate:) a výsledek se vrací prostřednictvím delegáta AVCapturePhotoCaptureDelegate.
Při práci s fotoaparátem na mobilních zařízeních je třeba zohlednit hardwarová omezení: zahřívání zařízení při dlouhém fotografování, vybíjení baterie při práci s vysokým rozlišením a rozdílnou kvalitu fotoaparátů na různých zařízeních. Na Androidu fragmentace ekosystému vede k tomu, že stejná konfigurace CameraX může fungovat odlišně na různých modelech. Na iOS se omezení týkají především licencování: použití fotoaparátu na pozadí vyžaduje zvláštní povolení od Apple. Je také důležité si uvědomit, že simulátory nemají přístup ke skutečnému fotoaparátu — testování je možné pouze na fyzickém zařízení.
CameraX řeší problém fragmentace Androidu prostřednictvím vrstvy kompatibility CameraXConfig — knihovna automaticky aplikuje obchůzky pro známé chyby výrobců. Na iOS AVFoundation funguje jednotně na všech zařízeních od iOS 6, ale některé funkce (např. Portrait Mode nebo LiDAR) jsou dostupné pouze na modelech iPhone 12 a novějších. Při vývoji multiplatformní aplikace se doporučuje používat Flutter nebo React Native s pluginy pro fotoaparát — abstrahují rozdíly platforem a poskytují jednotné API pro oba operační systémy.
Často kladené otázky
Pro většinu aplikací se doporučuje CameraX kvůli jednoduchosti použití, vestavěné správě životního cyklu a kompatibilitě s 95% zařízení. Camera2 volte pouze při potřebě RAW, sériového snímání nebo ručního ovládání senzoru.
Na Androidu přidejte oprávnění CAMERA do manifestu a požádejte o něj za běhu prostřednictvím ActivityCompat.requestPermissions. Na iOS přidejte NSCameraUsageDescription do Info.plist s jasným popisem důvodu použití fotoaparátu.
Na iOS je použití fotoaparátu na pozadí přísně omezeno — vyžaduje zvláštní povolení od Apple. Na Androidu může fotoaparát pracovat na pozadí prostřednictvím foreground service, ale to negativně ovlivňuje úroveň baterie a zahřívání zařízení.
Simulátory iOS a emulátory Androidu nemají přístup k hardwarovému fotoaparátu — neemulují fyzický senzor. Pro testování funkčnosti fotoaparátu vždy používejte fyzické zařízení nebo externí kameru připojenou k počítači.
ImageAnalysis — analyzátor proudu snímků z CameraX, který každý snímek předává ImageAnalysis.Analyzer ke zpracování. Používá se pro rozpoznávání QR kódů, detekci obličejů, skenování dokumentů a další úlohy počítačového vidění.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také