این صفحه معماری CameraX را پوشش میدهد، ازجمله ساختار آن، نحوه کار با API، نحوه کار با چرخههای حیات، و نحوه ترکیب موارد استفاده.
ساختار CameraX
میتوانید از CameraX برای تعامل با دوربین دستگاه ازطریق انتزاعی بهنام مورد استفاده استفاده کنید. موارد استفاده زیر دردسترس است:
- پیشنمایش: سطحی را برای نمایش پیشنمایش میپذیرد، مانند
PreviewView. - تجزیهوتحلیل تصویر: میانگیرهای قابلدسترسی برای CPU را برای تجزیهوتحلیل، مثلاً برای یادگیری ماشین، ارائه میدهد.
- ضبط تصویر: عکس میگیرد و ذخیره میکند.
- ضبط ویدیو: ضبط ویدیو و صدا با
VideoCapture
موارد استفاده را میتوان ترکیب کرد و بهطور همزمان فعال کرد. برای مثال، برنامهای میتواند به کاربر اجازه دهد تصویری را که دوربین میبیند بااستفاده از مورد کاربرد پیشنمایش مشاهده کند، مورد کاربرد تجزیهوتحلیل تصویر داشته باشد که تعیین میکند آیا افراد در عکس لبخند میزنند یا نه، و مورد کاربرد ضبط تصویر داشته باشد تا وقتی لبخند میزنند عکس بگیرد.
مدل میانای برنامهسازی کاربردی
برای کار با کتابخانه، موارد زیر را مشخص میکنید:
- مورد استفاده مطلوب با گزینههای پیکربندی.
- با پیوست کردن شنوندگان، با دادههای خروجی چه باید کرد.
- جریان موردنظر، مثلاً زمان فعال کردن دوربینها و زمان تولید داده، با مقید کردن مورد استفاده به چرخههای حیات معماری Android.
دو روش برای نوشتن برنامه CameraX وجود دارد:
CameraController (اگر میخواهید سادهترین روش را برای استفاده از CameraX داشته باشید، عالی است) یا
CameraProvider (اگر به انعطافپذیری بیشتری نیاز دارید، عالی است).
CameraController
CameraController بیشتر عملکردهای اصلی CameraX را در یک کلاس واحد ارائه میدهد. این ابزار به کد راهاندازی کمی نیاز دارد و بهطور خودکار مقداردهی اولیه دوربین، مدیریت مورد استفاده، چرخش هدف، ضربه زدن برای فوکوس، نیشگون گرفتن برای بزرگنمایی، و موارد دیگر را انجام میدهد. کلاس بتنی که CameraController را گسترش میدهد
LifecycleCameraController است.
val previewView: PreviewView = viewBinding.previewView var cameraController = LifecycleCameraController(baseContext) cameraController.bindToLifecycle(this) cameraController.cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA previewView.controller = cameraController
UseCaseهای پیشفرض برای CameraController عبارتند از Preview، ImageCapture، و
ImageAnalysis. برای خاموش کردن ImageCapture یا ImageAnalysis، یا برای روشن کردن
VideoCapture، از روش
setEnabledUseCases()
استفاده کنید.
برای موارد استفاده بیشتر از CameraController،
نمونه کدخوان پاسخسریع
یا
ویدیو اصول اولیه CameraController را ببینید.
CameraProvider
استفاده از CameraProvider همچنان آسان است، اما چون توسعهدهنده نرمافزار بخش بیشتری از راهاندازی را انجام میدهد، فرصتهای بیشتری برای سفارشیسازی پیکربندی وجود دارد، مانند فعال کردن چرخش تصویر خروجی یا تنظیم قالب تصویر خروجی در ImageAnalysis. همچنین میتوانید از Surface سفارشی برای پیشنمایش دوربین استفاده کنید که انعطافپذیری بیشتری را فراهم میکند، درحالیکه با CameraController ملزم به استفاده از PreviewView هستید. استفاده از کد Surface موجودتان میتواند مفید باشد اگر
ازقبل ورودی بخشهای دیگر برنامهتان باشد.
موارد استفاده را بااستفاده از روشهای set() پیکربندی میکنید و آنها را با روش build() نهایی میکنید. هر شیء مورد استفاده مجموعهای از میاناهای برنامهسازی کاربردی مختص مورد استفاده را ارائه میدهد. برای
مثال، مورد استفاده ضبط تصویر فراخوانی روش takePicture() را ارائه میدهد.
بهجای اینکه برنامه فراخوانیهای روش شروع و توقف خاصی را در
onResume() و onPause() قرار دهد، برنامه چرخه حیاتی را برای مرتبط کردن
دوربین با آن مشخص میکند، بااستفاده از
cameraProvider.bindToLifecycle().
سپس آن چرخه حیات به CameraX اطلاع میدهد که چه زمانی جلسه ضبط دوربین را پیکربندی کند
و مطمئن میشود که وضعیت دوربین بهطور مناسب تغییر میکند تا با انتقالهای چرخه حیات مطابقت داشته باشد.
برای مراحل پیادهسازی هر مورد استفاده، به پیادهسازی پیشنمایش، تجزیهوتحلیل تصاویر، ضبط تصویر، و ضبط ویدیو مراجعه کنید
مورد استفاده پیشنمایش با
Surface برای نمایش تعامل دارد. برنامهها
مورد استفاده را با گزینههای پیکربندی بااستفاده از کد زیر ایجاد میکنند:
val preview = Preview.Builder().build() val viewFinder: PreviewView = findViewById(R.id.previewView) // The use case is bound to an Android Lifecycle with the following code. val camera = cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview) // PreviewView creates a surface provider and is the recommended provider. preview.setSurfaceProvider(viewFinder.getSurfaceProvider())
برای کد نمونه بیشتر، به برنامه نمونه رسمی CameraX مراجعه کنید.
چرخههای حیات CameraX
CameraX چرخه حیاتی را مشاهده میکند تا تعیین کند چه زمانی دوربین را باز کند، چه زمانی جلسه ضبط ایجاد کند، و چه زمانی متوقف و خاموش شود. میاناهای برنامهسازی کاربردی مورد استفاده، فراخوانیهای روش و فراخوانیهای برگشتی را برای نظارت بر پیشرفت ارائه میدهند.
همانطور که در ترکیب کردن موارد استفاده توضیح داده شده است، میتوانید برخیاز ترکیبهای موارد استفاده را به یک چرخه حیات واحد متصل کنید. وقتی برنامهتان باید از موارد استفادهای پشتیبانی کند که نمیتوانند ترکیب شوند، میتوانید یکی از کارهای زیر را انجام دهید:
- موارد استفاده سازگار را در بیشاز یک قطعه گروهبندی کنید و سپس بین قطعهها جابهجا شوید
- ایجاد مؤلفه چرخه حیات سفارشی و استفاده از آن برای کنترل دستی چرخه حیات دوربین
اگر مالک «چرخه حیات» موارد استفاده از دوربین و نمای خود را از هم جدا کنید (برای مثال،
اگر از چرخه حیات سفارشی یا تکه
حفظشده استفاده کنید)، باید
مطمئن شوید که همه موارد استفاده بااستفاده از
ProcessCameraProvider.unbindAll()
یا با لغو اتصال هر مورد استفاده بهصورت جداگانه، از CameraX لغو اتصال شده باشند. یا وقتی موارد استفاده را به «چرخه حیات» مقید میکنید، میتوانید به CameraX اجازه دهید باز و بسته کردن جلسه ضبط و لغو قید موارد استفاده را مدیریت کند.
اگر همه عملکردهای دوربین شما با چرخه حیات یک مؤلفه آگاه از چرخه حیات، مانند
AppCompatActivity یا یک
AppCompat fragment، مطابقت دارد، استفاده از چرخه حیات آن مؤلفه هنگام اتصال
همه موارد استفاده مطلوب تضمین میکند که عملکرد دوربین زمانی که مؤلفه آگاه از چرخه حیات فعال است آماده باشد و بهطور ایمن دور ریخته شود و درغیراینصورت هیچ منبعی مصرف نکند.
LifecycleOwners سفارشی
برای موارد پیشرفته، میتوانید
LifecycleOwner سفارشی ایجاد کنید تا
برنامهتان بتواند بهجای گره زدن چرخه حیات جلسه CameraX به
LifecycleOwner استاندارد Android، آن را بهطور صریح کنترل کند.
نمونه کد زیر نحوه ایجاد یک LifecycleOwner سفارشی ساده را نشان میدهد:
class CustomLifecycle : LifecycleOwner { private val lifecycleRegistry: LifecycleRegistry init { lifecycleRegistry = LifecycleRegistry(this) lifecycleRegistry.currentState = Lifecycle.State.CREATED } // ... fun doOnResume() { lifecycleRegistry.currentState = State.RESUMED } // ... override val lifecycle: Lifecycle get() = lifecycleRegistry }
بااستفاده از این LifecycleOwner، برنامهتان میتواند انتقالهای حالت را در نقاط دلخواه در کد خود قرار دهد. برای اطلاعات بیشتر درباره پیادهسازی این عملکرد در برنامهتان،
پیادهسازی LifecycleOwner
سفارشی را ببینید.
موارد استفاده همزمان
موارد استفاده میتوانند بهطور همزمان اجرا شوند. While use cases can be sequentially bound to a
lifecycle, it is better to bind all use cases with a single call to
CameraProcessProvider.bindToLifecycle(). برای اطلاعات بیشتر درباره روالهای مطلوب برای تغییرات پیکربندی، به مدیریت تغییرات پیکربندی مراجعه کنید.
در نمونه کد زیر، برنامه دو مورد استفاده را برای ایجاد و اجرا بهطور همزمان مشخص میکند. همچنین چرخه حیات مورداستفاده برای هر دو مورد استفاده را مشخص میکند تا هر دو براساس چرخه حیات شروع و متوقف شوند.
private lateinit var imageCapture: ImageCapture override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val cameraProviderFuture = ProcessCameraProvider.getInstance(this) cameraProviderFuture.addListener( Runnable { // Camera provider is now guaranteed to be available. val cameraProvider = cameraProviderFuture.get() // Set up the preview use case to display camera preview. val preview = Preview.Builder().build() // Set up the capture use case to allow users to take photos. imageCapture = ImageCapture.Builder() .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY) .build() // Choose the camera by requiring a lens facing. val cameraSelector = CameraSelector.Builder() .requireLensFacing(CameraSelector.LENS_FACING_FRONT) .build() // Attach use cases to the camera with the same lifecycle owner. val camera = cameraProvider.bindToLifecycle( this as LifecycleOwner, cameraSelector, preview, imageCapture ) // Connect the preview use case to the previewView. preview.setSurfaceProvider( previewView.getSurfaceProvider() ) }, ContextCompat.getMainExecutor(this) ) }
CameraX امکان استفاده همزمان از یک نمونه از هرکدام از Preview،
VideoCapture، ImageAnalysis، و ImageCapture را فراهم میکند. بهعلاوه،
- هر مورد استفاده میتواند بهتنهایی کار کند. برای مثال، برنامه میتواند بدون استفاده از پیشنمایش، ویدیو ضبط کند.
- وقتی افزونهها فعال باشند، فقط ترکیب
ImageCaptureوPreviewتضمین میشود که کار کند. بسته به پیادهسازی OEM، ممکن است نتوانImageAnalysisرا نیز اضافه کرد؛ افزونهها را نمیتوان برای مورد استفادهVideoCaptureفعال کرد. برای جزئیات، سند مرجع افزونه را بررسی کنید. - بسته به قابلیت دوربین، برخیاز دوربینها ممکن است از این ترکیب در حالتهای وضوح پایینتر پشتیبانی کنند، اما نمیتوانند از همان ترکیب در برخیاز وضوحهای بالاتر پشتیبانی کنند.
- در دستگاههایی با سطح سختافزار دوربین
FULLیا پایینتر، ترکیبPreview،VideoCapture، وImageCaptureیاImageAnalysisممکن است CameraX را مجبور کند جاریسازیPRIVدوربین را برایPreviewوVideoCaptureتکرار کند. این تکثیر که همرسانی جاریسازی نامیده میشود، استفاده همزمان از این ویژگیها را ممکن میسازد اما به قیمت افزایش تقاضای پردازش تمام میشود. درنتیجه، ممکن است کمی تأخیر بیشتر و کاهش عمر باتری را تجربه کنید.
سطح سختافزار پشتیبانیشده
را میتوان از Camera2CameraInfo بازیابی کرد. برای مثال، کد زیر
بررسی میکند که آیا دوربین پشت پیشفرض دستگاه LEVEL_3 است یا نه:
@androidx.annotation.OptIn(ExperimentalCamera2Interop::class) fun isBackCameraLevel3Device(cameraProvider: ProcessCameraProvider): Boolean { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { return CameraSelector.DEFAULT_BACK_CAMERA .filter(cameraProvider.availableCameraInfos) .firstOrNull() ?.let { Camera2CameraInfo.from(it) } ?.getCameraCharacteristic(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3 } return false }
اجازهها
برنامه شما به اجازه
CAMERA نیاز خواهد داشت. برای
ذخیره کردن تصاویر در فایلها، به اجازه
WRITE_EXTERNAL_STORAGE
نیز نیاز دارد، بهجز در دستگاههایی که Android نسخه ۱۰ یا بالاتر دارند.
برای اطلاعات بیشتر درباره پیکربندی اجازهها برای برنامهتان، درخواست اجازههای برنامه را بخوانید.
الزامات
CameraX حداقل الزامات نسخه زیر را دارد:
- سطح ایپیآی Android نسخه ۲۱
- مؤلفههای معماری Android نسخه ۱.۱.۱
برای فعالیتهای آگاه از چرخه حیات، از
FragmentActivity یا
AppCompatActivity استفاده کنید.
اعلام وابستگیها
برای افزودن وابستگی به CameraX، باید مخزن Google Maven را به پروژهتان اضافه کنید.
فایل settings.gradle را برای پروژهتان باز کنید و مخزن google() را
همانطور که در زیر نشان داده شده است اضافه کنید:
شیک
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
کاتلین
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
موارد زیر را به انتهای بلوک Android اضافه کنید:
شیک
android { compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } // For Kotlin projects kotlinOptions { jvmTarget = "1.8" } }
کاتلین
android { compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } // For Kotlin projects kotlinOptions { jvmTarget = "1.8" } }
موارد زیر را به فایل build.gradle هر واحد برای برنامه اضافه کنید:
Groovy
dependencies { // CameraX core library using the camera2 implementation def camerax_version = "1.7.0-rc01" // The following line is optional, as the core library is included indirectly by camera-camera2 implementation "androidx.camera:camera-core:${camerax_version}" implementation "androidx.camera:camera-camera2:${camerax_version}" // If you want to additionally use the CameraX Lifecycle library implementation "androidx.camera:camera-lifecycle:${camerax_version}" // If you want to additionally use the CameraX VideoCapture library implementation "androidx.camera:camera-video:${camerax_version}" // If you want to additionally use the CameraX View class implementation "androidx.camera:camera-view:${camerax_version}" // If you want to additionally add CameraX ML Kit Vision Integration implementation "androidx.camera:camera-mlkit-vision:${camerax_version}" // If you want to additionally use the CameraX Extensions library implementation "androidx.camera:camera-extensions:${camerax_version}" }
Kotlin
dependencies { // CameraX core library using the camera2 implementation val camerax_version = "1.7.0-rc01" // The following line is optional, as the core library is included indirectly by camera-camera2 implementation("androidx.camera:camera-core:${camerax_version}") implementation("androidx.camera:camera-camera2:${camerax_version}") // If you want to additionally use the CameraX Lifecycle library implementation("androidx.camera:camera-lifecycle:${camerax_version}") // If you want to additionally use the CameraX VideoCapture library implementation("androidx.camera:camera-video:${camerax_version}") // If you want to additionally use the CameraX View class implementation("androidx.camera:camera-view:${camerax_version}") // If you want to additionally add CameraX ML Kit Vision Integration implementation("androidx.camera:camera-mlkit-vision:${camerax_version}") // If you want to additionally use the CameraX Extensions library implementation("androidx.camera:camera-extensions:${camerax_version}") }
برای کسب اطلاعات بیشتر درباره پیکربندی برنامهتان برای مطابقت با این الزامات، اعلام وابستگیها را ببینید.
تعاملپذیری CameraX با Camera2
CameraX براساس Camera2 ساخته شده است و CameraX روشهایی را برای خواندن و حتی نوشتن ویژگیها در پیادهسازی Camera2 ارائه میدهد. برای جزئیات کامل، بسته Interop را ببینید.
برای کسب اطلاعات بیشتر درباره نحوه پیکربندی ویژگیهای Camera2 توسط CameraX، از
Camera2CameraInfo
برای خواندن CameraCharacteristics زیربنایی استفاده کنید. همچنین میتوانید ویژگیهای Camera2 زیربنایی را در یکی از دو مسیر زیر بنویسید:
از
Camera2CameraControlاستفاده کنید، که به شما امکان میدهد ویژگیها را درCaptureRequestزیرین تنظیم کنید، مانند حالت فوکوس خودکار.گسترش دادن
UseCaseCameraX باCamera2Interop.Extender. این به شما امکان میدهد ویژگیهایی را در CaptureRequest تنظیم کنید، درست مانندCamera2CameraControl. همچنین کنترلهای بیشتری به شما میدهد، مثل تنظیم مورد استفاده جاریسازی برای بهینهسازی دوربین برای سناریو استفاده شما. برای اطلاعات بیشتر، به استفاده از موارد استفاده از جریان برای عملکرد بهتر مراجعه کنید.
نمونه کد زیر از موارد استفاده از جاریسازی برای بهینهسازی تماس ویدیویی استفاده میکند.
از Camera2CameraInfo
استفاده کنید تا ببینید آیا مورد استفاده جاریسازی تماس ویدیویی دردسترس است یا نه. سپس، از
Camera2Interop.Extender
برای تنظیم مورد استفاده جاریسازی زیربنایی استفاده کنید.
// Set underlying Camera2 stream use case to optimize for video calls. val videoCallStreamId = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL.toLong() // Check available CameraInfos to find the first one that supports // the video call stream use case. val frontCameraInfo = cameraProvider.getAvailableCameraInfos() .first { cameraInfo -> val isVideoCallStreamingSupported = Camera2CameraInfo.from(cameraInfo) .getCameraCharacteristic( CameraCharacteristics.SCALER_AVAILABLE_STREAM_USE_CASES )?.contains(videoCallStreamId) val isFrontFacing = (cameraInfo.getLensFacing() == CameraSelector.LENS_FACING_FRONT) (isVideoCallStreamingSupported == true) && isFrontFacing } val cameraSelector = frontCameraInfo.cameraSelector // Start with a Preview Builder. val previewBuilder = Preview.Builder() .setTargetAspectRatio(screenAspectRatio) .setTargetRotation(rotation) // Use Camera2Interop.Extender to set the video call stream use case. Camera2Interop.Extender(previewBuilder).setStreamUseCase(videoCallStreamId) // Bind the Preview UseCase and the corresponding CameraSelector. val preview = previewBuilder.build() camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview)
منابع بیشتر
برای کسب اطلاعات بیشتر درباره CameraX، به منابع تکمیلی زیر مراجعه کنید.
Codelab
نمونه کد