Камера в мобільних додатках — це апаратний модуль пристрою, доступний розробнику через системні API для захоплення зображень і відео. За даними Google Android Developers (2025), CameraX використовується в понад 85% додатків для Android, які потребують роботи з камерою. AVFoundation на iOS та CameraX на Android надають високорівневі інтерфейси, що приховують складність апаратного управління.
Головне
Мобільна камера — це вбудований оптичний модуль, що складається з об'єктива, матриці (сенсора) та процесора обробки зображень (ISP). Розробник отримує доступ до камери через операційну систему за допомогою спеціальних фреймворків. На Android це Camera2 API (низькорівневий) та CameraX (високорівневий на основі Camera2), на iOS — AVFoundation та UIKit для простих сценаріїв. Кожна платформа надає свій набір інструментів, але загальна концепція однакова: додаток ініціалізує сесію захоплення, налаштовує параметри (роздільна здатність, фокус, експозиція) та отримує потік кадрів або окремі зображення.
Сучасні мобільні камери підтримують безліч режимів зйомки: HDR, нічний режим, портретний з розмиттям фону, сповільнене відео та запис у форматі RAW. Для розробника доступні програмні налаштування: ISO (чутливість матриці), витримка (експозиція), баланс білого, фокус (автоматичний та ручний) та стабілізація зображення. На флагманських пристроях доступно до 4 камер з різними фокусними відстанями, і додаток може вибирати конкретну камеру за ID.
На мобільних платформах існує кілька API для роботи з камерою, які відрізняються за рівнем абстракції та функціональності. Вибір конкретного API залежить від вимог проекту: для простого захоплення фото достатньо CameraX або UIImagePickerController, для професійних додатків необхідний Camera2 або AVFoundation з прямим управлінням сенсором. Нижче наведено порівняння основних API.
| API | Платформа | Рівень | Особливості |
|---|---|---|---|
| CameraX | Android | Високий | Lifecycle-aware, 95% пристроїв |
| Camera2 | Android | Низький | Повний контроль, RAW, Burst |
| AVFoundation | iOS | Середній | Повний контроль захоплення |
| UIKit (UIImagePickerController) | iOS | Високий | Готовий UI, без кастомізації |
CameraX — оптимальний вибір для більшості Android-додатків, яким потрібна камера без поглибленої кастомізації. Бібліотека автоматично обробляє життєвий цикл Activity та Fragment, підтримує дозволи та сумісність з різними версіями Android. CameraX гарантує однакову поведінку на 95% пристроїв Android завдяки шару сумісності. Якщо потрібен попередній перегляд камери (Preview), захоплення фото (ImageCapture) або аналіз потоку (ImageAnalysis) — CameraX справляється з усіма трьома сценаріями без написання складного коду.
Camera2 — низькорівневий API для професійних сценаріїв: запис у RAW, ручне налаштування експозиції, burst-зйомка, управління кількома камерами одночасно. Camera2 вимагає від розробника глибокого розуміння конвеєра захоплення зображень, управління StateMachine та обробки callback-ів. Використовуйте Camera2 тільки якщо CameraX не покриває вимоги: наприклад, для додатків сканування документів з ручним фокусуванням або кастомних камер з нестандартною роздільною здатністю.
Доступ до камери вимагає явного дозволу користувача на обох платформах. На Android до маніфесту додається CAMERA permission, а починаючи з Android 6.0 необхідно також запитувати дозвіл під час виконання через ActivityCompat.requestPermissions. На iOS у Info.plist додається ключ NSCameraUsageDescription з описом причини використання камери. Без цього опису додаток буде аварійно завершено при спробі доступу до камери. Починаючи з iOS 14, у діалозі дозволів відображається не лише назва додатку, але й вказана причина — формулювання має бути зрозумілим користувачу.
CameraX спрощує роботу з камерою до кількох рядків коду. Для запуску попереднього перегляду необхідно створити екземпляр Preview, прив'язати його до LifecycleOwner та отримати SurfaceProvider для відображення. Для захоплення фото використовується ImageCapture з таргетом збереження. Нижче наведено повний приклад запуску камери та зйомки фотографії за допомогою CameraX на Kotlin.
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", "Помилка прив'язки", e)
}
}, ContextCompact.getMainExecutor(this))
Метод bindToLifecycle прив'язує камеру до життєвого циклу Activity — при повороті екрану або переході у фон камера автоматично звільняється. CameraSelector.DEFAULT_BACK_CAMERA вибирає тилову камеру, для фронтальної використовується DEFAULT_FRONT_CAMERA. Після прив'язки Preview починає відображати зображення з камери в PreviewView, і користувач бачить картинку з камери на екрані.
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", "Помилка захоплення", exception)
}
}
)
Метод takePicture виконує захоплення кадру з камери та зберігає його у файл. OutputFileOptions підтримує запис у File, ContentResolver та MediaStore. У callback onImageSaved додаток отримує повідомлення про успішне збереження та може оновити UI. CAPTURE_MODE_MINIMIZE_LATENCY забезпечує максимальну швидкість спрацьовування затвора за рахунок зменшення постобробки.
На iOS доступ до камери надає фреймворк AVFoundation через клас AVCaptureSession. Розробник створює сесію захоплення, додає необхідні входи (AVCaptureDeviceInput) та виходи (AVCapturePhotoOutput, AVCaptureVideoDataOutput) і запускає сесію. Для відображення попереднього перегляду використовується AVCaptureVideoPreviewLayer. Нижче наведено приклад налаштування сесії для захоплення фото на Swift.
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 встановлює оптимальну роздільну здатність для фото (зазвичай 12 МП на сучасних пристроях). Входом є AVCaptureDeviceInput, створений для камери пристрою. Після додавання входу та виходу сесія запускається у фоновому потоці через startRunning — запуск сесії може займати до 200 мс на старих пристроях. Для захоплення фото викликається capturePhoto(with:delegate:), і результат повертається через делегат AVCapturePhotoCaptureDelegate.
При роботі з камерою на мобільних пристроях необхідно враховувати апаратні обмеження: нагрів пристрою при тривалій зйомці, розряд батареї при роботі з високою роздільною здатністю та різну якість камер на різних пристроях. На Android фрагментація екосистеми призводить до того, що одна й та сама CameraX-конфігурація може працювати по-різному на різних моделях. На iOS обмеження стосуються в основному ліцензування: при використанні камери у фоні потрібен окремий дозвіл Apple. Також важливо пам'ятати, що симулятори не мають доступу до реальної камери — тестування можливе лише на фізичному пристрої.
CameraX вирішує проблему фрагментації Android через шар сумісності CameraXConfig — бібліотека автоматично застосовує обхідні шляхи для відомих багів виробників. На iOS AVFoundation працює однаково на всіх пристроях, починаючи з iOS 6, але деякі функції (наприклад, Portrait Mode або LiDAR) доступні лише на моделях iPhone 12 та новіших. При розробці кроссплатформного додатку рекомендується використовувати Flutter або React Native з плагінами камери — вони абстрагують платформні відмінності та надають єдиний API для обох ОС.
Часті запитання
Для більшості додатків рекомендується CameraX через простоту використання, вбудовану обробку життєвого циклу та сумісність з 95% пристроїв. Camera2 варто вибирати тільки при необхідності RAW, burst-зйомки або ручного управління сенсором.
На Android додайте CAMERA permission до маніфесту та запитайте його під час виконання через ActivityCompat.requestPermissions. На iOS додайте NSCameraUsageDescription до Info.plist зі зрозумілим описом причини використання камери.
На iOS використання камери у фоні суворо обмежено — потрібен спеціальний дозвіл Apple. На Android камера може працювати у фоні через foreground service, але це негативно впливає на заряд батареї та нагрів пристрою.
Симулятори iOS та емулятори Android не мають доступу до апаратної камери — вони не емулюють фізичний сенсор. Для тестування функціональності камери завжди використовуйте фізичний пристрій або зовнішню камеру, підключену до комп'ютера.
ImageAnalysis — це аналізатор потоку кадрів з CameraX, який передає кожен кадр у ImageAnalysis.Analyzer для обробки. Використовується для розпізнавання QR-кодів, виявлення облич, сканування документів та інших завдань комп'ютерного зору.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також