يسرّ فريق CameraX الإعلان عن إصدار النسخة 1.5. يركّز هذا التحديث الأخير على توفير إمكانات احترافية بين أيديكم، مع تسهيل إعداد جلسة الكاميرا أكثر من أي وقت مضى.
بالنسبة إلى تسجيل الفيديوهات، يمكن للمستخدمين الآن تسجيل فيديوهات مذهلة بسهولة في وضع "التصوير البطيء" أو بمعدّل إطارات مرتفع. والأهم من ذلك، تتيح لكم واجهة Feature Group API الجديدة تفعيل مجموعات معقّدة من الميزات بثقة، مثل فيديو 10 بت بنطاق عالي الديناميكية و60 لقطة في الثانية، ما يضمن الحصول على نتائج متّسقة على الأجهزة المتوافقة.
في ما يتعلق بالتقاط الصور ، يمكنكم الاستفادة من أقصى قدر من المرونة من خلال إمكانية التقاط ملفات DNG (RAW) غير معالَجة وغير مضغوطة. بالإضافة إلى ذلك، يمكنكم الآن الاستفادة من ميزة "دقة HDR فائقة" حتى عند استخدام "إضافات الكاميرا" القوية.
تستند هذه الميزات إلى واجهة SessionConfig API الجديدة التي تُبسّط عملية إعداد الكاميرا وإعادة ضبطها. لننتقل الآن إلى تفاصيل هذه الميزات الجديدة الرائعة.
تسجيل فيديوهات فعّال: سرعة عالية ومجموعات من الميزات
توسّع النسخة 1.5 من CameraX إمكانات تسجيل الفيديوهات بشكلٍ كبير، ما يتيح تجارب تسجيل أكثر إبداعًا وقوة.
فيديو في وضع "التصوير البطيء" وبمعدّل إطارات مرتفع
تتوفّر الآن ميزة "فيديو في وضع التصوير البطيء" التي طال انتظارها. يمكنكم الآن تسجيل فيديوهات عالية السرعة (مثل 120 أو 240 لقطة في الثانية) وتشفيرها مباشرةً في فيديو مذهل في وضع "التصوير البطيء". يمكنكم بدلاً من ذلك التسجيل بعدد اللقطات في الثانية المرتفع نفسه لإنتاج فيديو سلس للغاية.
إنّ تنفيذ هذه الميزة سهل إذا كنتم على دراية بواجهة VideoCapture API.
1. التحقّق من إمكانية استخدام السرعة العالية: استخدِموا طريقة Recorder.getHighSpeedVideoCapabilities() الجديدة للاستعلام عمّا إذا كان الجهاز يتيح استخدام هذه الميزة.
val cameraInfo = cameraProvider.getCameraInfo(cameraSelector)
val highSpeedCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo)
if (highSpeedCapabilities == null) {
// This camera device does not support high-speed video.
return
}2. ضبط حالة الاستخدام وربطها: استخدِموا videoCapabilities التي تم عرضها (والتي تحتوي على معلومات عن جودة الفيديو المتوافقة) لإنشاء HighSpeedVideoSessionConfig. يجب بعد ذلك الاستعلام عن نطاقات عدد اللقطات في الثانية المتوافقة من خلال cameraInfo.getSupportedFrameRateRanges() وضبط النطاق المطلوب. استدعوا setSlowMotionEnabled(true) لتسجيل فيديوهات في وضع "التصوير البطيء"، وإلا سيتم تسجيل فيديوهات بمعدّل إطارات مرتفع. الخطوة الأخيرة هي استخدام Recorder.prepareRecording().start() العادية لبدء تسجيل الفيديو.
val preview = Preview.Builder().build()
val quality = highSpeedCapabilities
.getSupportedQualities(DynamicRange.SDR).first()
val recorder = Recorder.Builder()
.setQualitySelector(QualitySelector.from(quality)))
.build()
val videoCapture = VideoCapture.withOutput(recorder)
val frameRateRange = cameraInfo.getSupportedFrameRateRanges(
HighSpeedVideoSessionConfig(videoCapture, preview)
).first()
val sessionConfig = HighSpeedVideoSessionConfig(
videoCapture,
preview,
frameRateRange = frameRateRange,
// Set true for slow-motion playback, or false for high-frame-rate
isSlowMotionEnabled = true
)
cameraProvider.bindToLifecycle(
lifecycleOwner, cameraSelector, sessionConfig)
// Start recording slow motion videos.
val recording = recorder.prepareRecording(context, outputOption)
.start(executor, {})التوافق والقيود
يتطلّب التسجيل عالي السرعة توفّر دعم معيّن لـ CameraConstrainedHighSpeedCaptureSession وCamcorderProfile. يجب دائمًا إجراء عملية التحقّق من الإمكانات، وتفعيل التسجيل عالي السرعة على الأجهزة المتوافقة فقط لمنع تجربة المستخدم السيئة. تتوفّر هذه الميزة حاليًا على الكاميرات الخلفية في جميع أجهزة Pixel تقريبًا ونماذج معيّنة من جهات تصنيع أخرى.
يمكنكم الاطّلاع على منشور المدونة لمزيد من التفاصيل.
الجمع بين الميزات بثقة: واجهة Feature Group API
تقدّم النسخة 1.5 من CameraX واجهة Feature Group API التي تزيل التخمينات بشأن توافق الميزات. استنادًا إلى واجهة برمجة التطبيقات للاستعلام عن مجموعات الميزات في Android 15، يمكنكم الآن تفعيل ميزات متعدّدة معًا بثقة، ما يضمن الحصول على جلسة كاميرا ثابتة. تتوفّر حاليًا الميزات التالية في "مجموعة الميزات": النطاق العالي الديناميكية (HLG) و60 لقطة في الثانية و"تثبيت المعاينة" و"دقة HDR فائقة". على سبيل المثال، يمكنكم تفعيل النطاق العالي الديناميكية و60 لقطة في الثانية و"تثبيت المعاينة" في الوقت نفسه على سلسلتَي Pixel 10 وGalaxy S25. من المخطط إجراء تحسينات مستقبلية تشمل التسجيل بدقة 4K والتكبير/التصغير بزاوية فائقة الاتساع.
تتيح واجهة برمجة التطبيقات لمجموعة الميزات حالتَي استخدام أساسيتَين:
حالة الاستخدام 1: منح الأولوية لأفضل جودة
إذا أردتم التقاط الصور باستخدام أفضل مجموعة ممكنة من الميزات، يمكنكم تقديم قائمة مرتّبة حسب الأولوية. سيحاول CameraX تفعيلها بالترتيب، واختيار المجموعة الأولى التي يتيحها الجهاز بالكامل.
val sessionConfig = SessionConfig(
useCases = listOf(preview, videoCapture),
preferredFeatureGroup = listOf(
GroupableFeature.HDR_HLG10,
GroupableFeature.FPS_60,
GroupableFeature.PREVIEW_STABILIZATION
)
).apply {
// (Optional) Get a callback with the enabled features to update your UI.
setFeatureSelectionListener { selectedFeatures ->
updateUiIndicators(selectedFeatures)
}
}
processCameraProvider.bindToLifecycle(activity, cameraSelector, sessionConfig)في هذا المثال، يحاول CameraX تفعيل الميزات بهذا الترتيب:
- النطاق العالي الديناميكية + 60 لقطة في الثانية + "تثبيت المعاينة"
- النطاق العالي الديناميكية + 60 لقطة في الثانية
- النطاق العالي الديناميكية + "تثبيت المعاينة"
- النطاق العالي الديناميكية
- 60 لقطة في الثانية + "تثبيت المعاينة"
- 60 لقطة في الثانية
- "تثبيت المعاينة"
- بدون
حالة الاستخدام 2: إنشاء واجهة مستخدم للإعدادات يمكن للمستخدمين التفاعل معها
يمكنكم الآن عرض مجموعات الميزات المتوافقة بدقة في واجهة مستخدم الإعدادات في تطبيقكم، وإيقاف أزرار التبديل للخيارات غير المتوافقة، مثل الصورة أدناه.
لتحديد ما إذا كان يجب تعتيم زر التبديل، استخدِموا الرموز التالية للتحقّق من إمكانية استخدام مجموعة الميزات. في البداية، استعلموا عن حالة كل ميزة فردية. بعد تفعيل ميزة، أعيدوا الاستعلام عن الميزات المتبقية باستخدام الميزات المفعّلة لمعرفة ما إذا كان يجب تعتيم أزرار التبديل الخاصة بها الآن بسبب قيود التوافق.
fun disableFeatureIfNotSuported(
enabledFeatures: Set<GroupableFeature>,
featureToCheck:GroupableFeature
) {
val sessionConfig = SessionConfig(
useCases = useCases,
requiredFeatureGroup = enabledFeatures + featureToCheck
)
val isSupported = cameraInfo.isFeatureGroupSupported(sessionConfig)
if (!isSupported) {
// disable the toggle for featureToCheck
}
}يُرجى الرجوع إلى منشور المدونة Feature Group لمزيد من المعلومات.
تحسينات إضافية على الفيديو
- تحسينات على الكاميرا المتزامنة: باستخدام CameraX 1.5.1، يمكنكم الآن ربط حالات استخدام "المعاينة" وImageCapture وVideoCapture بشكلٍ متزامن لكل SingleCameraConfig في وضع عدم التركيب. بالإضافة إلى ذلك، في وضع التركيب (حالات الاستخدام نفسها مع CompositionSettings)، يمكنكم الآن ضبط
CameraEffectالذي يتم تطبيقه على نتيجة التركيب النهائية. - كتم الصوت بشكلٍ ديناميكي: يمكنكم الآن بدء التسجيل في حالة كتم الصوت باستخدام
PendingRecording.withAudioEnabled(boolean initialMuted)والسماح للمستخدم بإلغاء كتم الصوت لاحقًا باستخدامRecording.mute(boolean muted). - معالجة محسَّنة لمشكلة عدم توفّر مساحة تخزين كافية: يرسل CameraX الآن بشكلٍ موثوق الخطأ
VideoRecordEvent.Finalize.ERROR_INSUFFICIENT_STORAGE، ما يتيح لتطبيقكم معالجة حالات انخفاض مساحة التخزين بشكلٍ سلس وإعلام المستخدم. - تحسين الإضاءة المنخفضة: على الأجهزة المتوافقة (مثل سلسلة Pixel 10)، يمكنكم تفعيل CameraControl.enableLowLightBoostAsync لتفتيح المعاينة وفيديوهات البث تلقائيًا في البيئات المظلمة.
التقاط صور احترافي
تقدّم النسخة 1.5 من CameraX ترقيات كبيرة إلى ImageCapture للمطوّرين الذين يطلبون أقصى قدر من الجودة والمرونة.
إطلاق العنان للتحكّم الإبداعي باستخدام ميزة التقاط صور بتنسيق DNG (RAW)
للحصول على تحكّم كامل في مرحلة ما بعد المعالجة، يتيح CameraX الآن التقاط الصور بتنسيق DNG (RAW). يمنحكم ذلك إمكانية الوصول إلى بيانات الصور غير المعالَجة وغير المضغوطة مباشرةً من مستشعر الكاميرا، ما يتيح إجراء عمليات تعديل وتصحيح الألوان احترافية. تتيح واجهة برمجة التطبيقات التقاط ملف DNG وحده، أو التقاط مخرجات JPEG وDNG في الوقت نفسه. يمكنكم الاطّلاع على نموذج الرمز أدناه لمعرفة كيفية التقاط ملفات JPEG وDNG في الوقت نفسه.
val capabilities = ImageCapture.getImageCaptureCapabilities(cameraInfo)
val imageCapture = ImageCapture.Builder().apply {
if (capabilities.supportedOutputFormats
.contains(OUTPUT_FORMAT_RAW_JPEG)) {
// Capture both RAW and JPEG formats.
setOutputFormat(OUTPUT_FORMAT_RAW_JPEG)
}
}.build()
// ... bind imageCapture to lifecycle ...
// Provide separate output options for each format.
val outputOptionRaw = /* ... configure for image/x-adobe-dng ... */
val outputOptionJpeg = /* ... configure for image/jpeg ... */
imageCapture.takePicture(
outputOptionRaw,
outputOptionJpeg,
executor,
object : ImageCapture.OnImageSavedCallback {
override fun onImageSaved(results: OutputFileResults) {
// This callback is invoked twice: once for the RAW file
// and once for the JPEG file.
}
override fun onError(exception: ImageCaptureException) {}
}
)دقة HDR فائقة لـ "إضافات الكاميرا"
يمكنكم الاستفادة من أفضل الميزات: التصوير الفوتوغرافي الحسابي المذهل لـ "إضافات الكاميرا" (مثل "الوضع الليلي") مع الألوان الرائعة والنطاق الديناميكي لميزة "دقة HDR فائقة". تتوفّر هذه الميزة الآن على العديد من هواتف Android المميّزة الحديثة، مثل سلسلتَي Pixel 9/10 وSamsung S24/S25.
// Support UltraHDR when Extension is enabled.
val extensionsEnabledCameraSelector = extensionsManager
.getExtensionEnabledCameraSelector(
CameraSelector.DEFAULT_BACK_CAMERA, ExtensionMode.NIGHT)
val imageCapabilities = ImageCapture.getImageCaptureCapabilities(
cameraProvider.getCameraInfo(extensionsEnabledCameraSelector)
val imageCapture = ImageCapture.Builder()
.apply {
if (imageCapabilities.supportedOutputFormats
.contains(OUTPUT_FORMAT_JPEG_ULTRA_HDR) {
setOutputFormat(OUTPUT_FORMAT_JPEG_ULTRA_HDR)
}
}.build()تحسينات على واجهة برمجة التطبيقات الأساسية وسهولة الاستخدام
طريقة جديدة للضبط: SessionConfig
كما هو موضّح في الأمثلة أعلاه، إنّ SessionConfig مفهوم جديد في CameraX 1.5. تُركّز هذه الميزة عملية الضبط وتُبسّط واجهة برمجة التطبيقات بطريقتَين رئيسيتَين:
- لن تحتاجوا بعد الآن إلى استدعاء
unbind()يدويًا: تتوافق واجهات برمجة تطبيقات CameraX مع مراحل النشاط. ستؤدي هذه الواجهات تلقائيًا إلى "إلغاء ربط" حالات الاستخدام عند إيقاف النشاط أوLifecycleOwnerالآخر. ولكنّ تعديل حالات الاستخدام أو تبديل الكاميرات لا يزال يتطلّب استدعاءunbind()أوunbindAll()قبل إعادة الربط. باستخدام CameraX 1.5، عندما تربطونSessionConfigجديدًا، يحدّث CameraX الجلسة بسلاسة نيابةً عنكم، ما يزيل الحاجة إلى استدعاء عمليات إلغاء الربط. - التحكّم في عدد اللقطات في الثانية بشكلٍ محدّد: تقدّم واجهة
SessionConfigAPI الجديدة طريقة محدّدة لإدارة عدد اللقطات في الثانية. على عكس طريقةsetTargetFrameRateالسابقة التي كانت مجرد إشارة، تضمن هذه الطريقة الجديدة تطبيق نطاق عدد اللقطات في الثانية المحدّد عند نجاح عملية الضبط. لضمان الدقة، يجب الاستعلام عن معدّلات الإطارات المتوافقة باستخدامCameraInfo.getSupportedFrameRateRanges(SessionConfig). من خلال تمريرSessionConfigالكامل، يمكن لـ CameraX تحديد النطاقات المتوافقة بدقة استنادًا إلى إعدادات البث.
أصبحت مكتبة Camera-Compose مستقرة الآن
نعرف مدى إعجابكم بمكتبة Jetpack Compose، ويسرّنا الإعلان عن أنّ مكتبة camera-compose أصبحت مستقرة الآن في الإصدار 1.5.1! يتضمّن هذا الإصدار إصلاحات مهمة للأخطاء المتعلقة باستخدام CameraXViewfinder مع ميزات Compose، مثل moveableContentOf وPager، بالإضافة إلى حلّ مشكلة تمديد المعاينة. سنواصل إضافة المزيد من الميزات إلى camera-compose في الإصدارات المستقبلية.
تحسينات على ImageAnalysis وCameraControl
- ضبط قوة المصباح اليدوي: يمكنكم التحكّم بدقة في المصباح اليدوي للجهاز باستخدام واجهات برمجة التطبيقات الجديدة. يمكنكم الاستعلام عن الحد الأقصى للقوة المتوافقة باستخدام CameraInfo.getMaxTorchStrengthLevel() ثم ضبط المستوى المطلوب باستخدام CameraControl.setTorchStrengthLevel().
- إمكانية استخدام تنسيق NV21 في
ImageAnalysis: يمكنكم الآن طلب تنسيق الصورة NV21 مباشرةً منImageAnalysis، ما يُبسّط عملية التكامل مع المكتبات وواجهات برمجة التطبيقات الأخرى. يتم تفعيل هذه الميزة من خلال استدعاءImageAnalysis.Builder.setOutputImageFormat(OUTPUT_IMAGE_FORMAT_NV21).
البدء اليوم
عدِّلوا التبعيات إلى CameraX 1.5 اليوم واستكشِفوا الميزات الجديدة الرائعة. نتطلّع إلى رؤية ما ستنشئونه.
لاستخدام CameraX 1.5، يُرجى إضافة التبعيات التالية إلى ملف libs.versions.toml. (ننصح باستخدام الإصدار 1.5.1 الذي يحتوي على العديد من إصلاحات الأخطاء المهمة والتحسينات على الكاميرا المتزامنة.)
[versions]
camerax = "1.5.1"
[libraries]
..
androidx-camera-core = { module = "androidx.camera:camera-core", version.ref = "camerax" }
androidx-camera-compose = { module = "androidx.camera:camera-compose", version.ref = "camerax" }
androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "camerax" }
androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "camerax" }
androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "camerax" }
androidx-camera-extensions = { module = "androidx.camera:camera-extensions", version.ref = "camerax" }بعد ذلك، أضيفوا هذه التبعيات إلى ملف build.gradle.kts الخاص بالوحدة:
dependencies {
..
implementation(libs.androidx.camera.core)
implementation(libs.androidx.camera.lifecycle)
implementation(libs.androidx.camera.camera2)
implementation(libs.androidx.camera.view) // for PreviewView
implementation(libs.androidx.camera.compose) // for compose UI
implementation(libs.androidx.camera.extensions) // For Extensions
}هل لديكم أسئلة أو تريدون التواصل مع فريق CameraX؟ انضموا إلى مجموعة مناقشة المطوّرين في CameraX أو أبلغوا عن خطأ:
متابعة القراءة
-
أخبار المنتجات
في مؤتمر Google I/O 2026، قدّمنا تحوّل Android من نظام تشغيل إلى نظام ذكاء. أوضحنا أيضًا كيف يمكنكم إنشاء تجارب ذكية بشكلٍ أصلي باستخدام النظام وإضافة قوة الذكاء الاصطناعي من Google إلى تطبيقاتكم.
Jingyu Shi • مدة القراءة: دقيقتان
-
أخبار المنتجات
يسرّنا الإعلان عن توفّر الدعم الرسمي لـ Unreal Engine وGodot على Android XR. نطلق أيضًا أدوات جديدة مصمّمة لتعزيز إنتاجيتكم وتفعيل إمكانات XR جديدة: Android XR Engine Hub وAndroid XR Interaction Framework.
Luke Hopkins, Ryan Bartley • مدة القراءة: 4 دقائق
-
أخبار المنتجات
مع إصدار Android 17، ننتقل إلى معيار تطوير تكيّفي أولاً. لم يعُد المستخدمون يعتمدون على شكل جهاز واحد، بل ينتقلون بين الهواتف والهواتف القابلة للطي والأجهزة اللوحية وأجهزة الكمبيوتر المحمولة وشاشات السيارات وبيئات XR الغامرة على مدار اليوم.
Fahd Imtiaz • مدة القراءة: 4 دقائق
البقاء على اطّلاع على آخر التحديثات
يمكنكم تلقّي أحدث المعلومات عن تطوير تطبيقات Android أسبوعيًا في بريدكم الوارد.