कॉन्फ़िगरेशन विकल्प

CameraX के हर इस्तेमाल के उदाहरण को कॉन्फ़िगर किया जाता है, ताकि इस्तेमाल के उदाहरण के ऑपरेशन के अलग-अलग पहलुओं को कंट्रोल किया जा सके.

उदाहरण के लिए, इमेज कैप्चर करने के इस्तेमाल के उदाहरण के साथ, टारगेट आसपेक्ट रेशियो और फ़्लैश मोड सेट किया जा सकता है. यह कोड एक उदाहरण दिखाता है:

Kotlin

val imageCapture = ImageCapture.Builder()
    .setFlashMode(...)
    .setTargetAspectRatio(...)
    .build()

Java

ImageCapture imageCapture =
    new ImageCapture.Builder()
        .setFlashMode(...)
        .setTargetAspectRatio(...)
        .build();

कॉन्फ़िगरेशन के विकल्पों के अलावा, कुछ इस्तेमाल के उदाहरणों में एपीआई को दिखाया जाता है, ताकि इस्तेमाल के उदाहरण बनाने के बाद, सेटिंग को डाइनैमिक तौर पर बदला जा सके. अलग-अलग इस्तेमाल के उदाहरणों के हिसाब से कॉन्फ़िगरेशन के बारे में जानने के लिए, झलक लागू करना, इमेज का विश्लेषण करना, और इमेज कैप्चर करना लेख पढ़ें.

CameraXConfig

आसानी के लिए, CameraX में डिफ़ॉल्ट कॉन्फ़िगरेशन होते हैं. जैसे, इंटरनल एक्ज़ीक्यूटर और हैंडलर, जो इस्तेमाल के ज़्यादातर मामलों के लिए सही होते हैं. हालांकि, अगर आपके ऐप्लिकेशन के लिए कोई खास ज़रूरत है या आपको उन कॉन्फ़िगरेशन को पसंद के मुताबिक बनाना है, तो इसके लिए CameraXConfig इंटरफ़ेस का इस्तेमाल करें.

CameraXConfig की मदद से, कोई ऐप्लिकेशन ये काम कर सकता है:

  • setAvailableCameraLimiter() की मदद से, ऐप्लिकेशन के शुरू होने में लगने वाले समय को ऑप्टिमाइज़ करें.
  • setCameraExecutor() की मदद से, CameraX को ऐप्लिकेशन के एक्ज़ीक्यूटर की जानकारी दें.
  • डिफ़ॉल्ट शेड्यूलर हैंडलर को setSchedulerHandler() से बदलें.
  • setMinimumLoggingLevel() का इस्तेमाल करके, लॉगिंग लेवल बदलें.

इस्तेमाल का मॉडल

नीचे दिए गए प्रोसेस में, CameraXConfig के इस्तेमाल का तरीका बताया गया है:

  1. अपनी पसंद के मुताबिक बनाए गए कॉन्फ़िगरेशन के साथ CameraXConfig ऑब्जेक्ट बनाएं.
  2. अपने Application में CameraXConfig.Provider इंटरफ़ेस लागू करें और getCameraXConfig() में अपना CameraXConfig ऑब्जेक्ट दिखाएं.
  3. अपनी Application क्लास को अपनी AndroidManifest.xml फ़ाइल में जोड़ें, जैसा कि यहां बताया गया है.

उदाहरण के लिए, नीचे दिया गया कोड सैंपल, CameraX में लॉग इन करने के लिए सिर्फ़ गड़बड़ी के मैसेज को अनुमति देता है:

Kotlin

class CameraApplication : Application(), CameraXConfig.Provider {
   override fun getCameraXConfig(): CameraXConfig {
       return CameraXConfig.Builder.fromConfig(Camera2Config.defaultConfig())
           .setMinimumLoggingLevel(Log.ERROR).build()
   }
}

अगर आपके ऐप्लिकेशन को CameraX कॉन्फ़िगरेशन सेट करने के बाद, उसके बारे में जानकारी चाहिए, तो CameraXConfig ऑब्जेक्ट की लोकल कॉपी रखें.

कैमरा लिमिटर

ProcessCameraProvider.getInstance() को पहली बार इस्तेमाल करने पर, CameraX, डिवाइस पर उपलब्ध कैमरों की जानकारी देता है और उनके बारे में क्वेरी करता है. CameraX को हार्डवेयर कॉम्पोनेंट के साथ कम्यूनिकेट करना पड़ता है. इसलिए, हर कैमरे के लिए इस प्रोसेस में काफ़ी समय लग सकता है. खास तौर पर, कम-ऑफ़र वाले डिवाइसों पर. अगर आपका ऐप्लिकेशन डिवाइस पर सिर्फ़ कुछ कैमरों का इस्तेमाल करता है, जैसे कि डिफ़ॉल्ट तौर पर मौजूद सामने वाला कैमरा, तो CameraX को दूसरे कैमरों को अनदेखा करने के लिए सेट किया जा सकता है. इससे, आपके ऐप्लिकेशन के इस्तेमाल किए जाने वाले कैमरों के लिए, स्टार्टअप में लगने वाला समय कम हो सकता है.

अगर CameraXConfig.Builder.setAvailableCamerasLimiter() को पास किया गया CameraSelector किसी कैमरे को फ़िल्टर कर देता है, तो CameraX ऐसे काम करता है जैसे कि वह कैमरा मौजूद ही नहीं है. उदाहरण के लिए, नीचे दिया गया कोड, ऐप्लिकेशन को सिर्फ़ डिवाइस के डिफ़ॉल्ट बैक कैमरे का इस्तेमाल करने की अनुमति देता है:

Kotlin

class MainApplication : Application(), CameraXConfig.Provider {
   override fun getCameraXConfig(): CameraXConfig {
       return CameraXConfig.Builder.fromConfig(Camera2Config.defaultConfig())
              .setAvailableCamerasLimiter(CameraSelector.DEFAULT_BACK_CAMERA)
              .build()
   }
}

थ्रेड

CameraX को जिन प्लैटफ़ॉर्म एपीआई पर बनाया गया है उनमें से कई के लिए, हार्डवेयर के साथ इंटरप्रोसेस कम्यूनिकेशन (आईपीसी) को ब्लॉक करना ज़रूरी होता है. कभी-कभी, जवाब देने में सैकड़ों मिलीसेकंड लग सकते हैं. इस वजह से, CameraX सिर्फ़ बैकग्राउंड थ्रेड से इन एपीआई को कॉल करता है, ताकि मुख्य थ्रेड ब्लॉक न हो और यूज़र इंटरफ़ेस (यूआई) बेहतर तरीके से काम करता रहे. CameraX, इन बैकग्राउंड थ्रेड को इंटरनल तौर पर मैनेज करता है, ताकि यह व्यवहार पारदर्शी लगे. हालांकि, कुछ ऐप्लिकेशन के लिए थ्रेड को सख्ती से कंट्रोल करना ज़रूरी होता है. CameraXConfig की मदद से, ऐप्लिकेशन उन बैकग्राउंड थ्रेड को सेट कर सकता है जिनका इस्तेमाल CameraXConfig.Builder.setCameraExecutor() और CameraXConfig.Builder.setSchedulerHandler() के ज़रिए किया जाता है.

Camera Executor

Camera Executor का इस्तेमाल, Camera प्लैटफ़ॉर्म के सभी इंटरनल एपीआई कॉल के साथ-साथ, इन एपीआई से मिलने वाले कॉलबैक के लिए भी किया जाता है. इन टास्क को पूरा करने के लिए, CameraX एक इंटरनल Executor को असाइन और मैनेज करता है. हालांकि, अगर आपके ऐप्लिकेशन को थ्रेड पर ज़्यादा कंट्रोल की ज़रूरत है, तो CameraXConfig.Builder.setCameraExecutor() का इस्तेमाल करें.

शेड्यूलर हैंडलर

शेड्यूलर हैंडलर का इस्तेमाल, अंदरूनी टास्क को तय अंतराल पर शेड्यूल करने के लिए किया जाता है. जैसे, कैमरा उपलब्ध न होने पर उसे फिर से खोलने की कोशिश करना. यह हैंडलर, टास्क को पूरा नहीं करता. यह सिर्फ़ उन्हें कैमरा एक्ज़ीक्यूटर को भेजता है. इसका इस्तेमाल कभी-कभी पुराने एपीआई प्लैटफ़ॉर्म पर भी किया जाता है. इन्हें कॉलबैक करने के लिए, Handler की ज़रूरत होती है. ऐसे मामलों में, कॉलबैक अब भी सीधे कैमरा एक्ज़िक्यूटर को भेजे जाते हैं. CameraX, इन टास्क को पूरा करने के लिए, एक इंटरनल HandlerThread को असाइन और मैनेज करता है. हालांकि, इसे CameraXConfig.Builder.setSchedulerHandler() से बदला जा सकता है.

लॉग इन हो रहा है

CameraX में लॉग इन करने की सुविधा की मदद से, ऐप्लिकेशन लॉगकैट मैसेज को फ़िल्टर कर सकते हैं. ऐसा इसलिए, क्योंकि आपके प्रोडक्शन कोड में बहुत ज़्यादा शब्दों वाले मैसेज से बचना बेहतर होता है. CameraX में लॉगिंग के चार लेवल होते हैं. इनमें सबसे ज़्यादा जानकारी देने वाले से लेकर सबसे गंभीर लेवल तक शामिल हैं:

  • Log.DEBUG (डिफ़ॉल्ट)
  • Log.INFO
  • Log.WARN
  • Log.ERROR

इन लॉग लेवल के बारे में ज़्यादा जानकारी के लिए, Android लॉग दस्तावेज़ देखें. अपने ऐप्लिकेशन के लिए सही लॉगिंग लेवल सेट करने के लिए, CameraXConfig.Builder.setMinimumLoggingLevel(int) का इस्तेमाल करें.

अपने-आप चुनना

CameraX अपने-आप उस डिवाइस की सुविधाएं देता है जिस पर आपका ऐप्लिकेशन चल रहा है. उदाहरण के लिए, अगर आपने कोई रिज़ॉल्यूशन तय नहीं किया है या आपका तय किया गया रिज़ॉल्यूशन काम नहीं करता है, तो CameraX अपने-आप सबसे अच्छा रिज़ॉल्यूशन तय कर लेता है. यह लाइब्रेरी ही इन सभी कामों को मैनेज करती है. इससे, आपको डिवाइस के हिसाब से कोड लिखने की ज़रूरत नहीं पड़ती.

CameraX का लक्ष्य, कैमरा सेशन को शुरू करना है. इसका मतलब है कि डिवाइस की क्षमता के आधार पर, CameraX रिज़ॉल्यूशन और आसपेक्ट रेशियो में बदलाव करता है. डेटा का गलत इस्तेमाल इन वजहों से हो सकता है:

  • डिवाइस, अनुरोध किए गए रिज़ॉल्यूशन पर काम नहीं करता.
  • डिवाइस पर साथ काम करने से जुड़ी समस्याएं हैं. जैसे, लेगसी डिवाइस जिन्हें ठीक से काम करने के लिए, कुछ खास रिज़ॉल्यूशन की ज़रूरत होती है.
  • कुछ डिवाइसों पर, कुछ फ़ॉर्मैट सिर्फ़ खास आसपेक्ट रेशियो पर उपलब्ध होते हैं.
  • डिवाइस में JPEG या वीडियो को एन्कोड करने के लिए, "नियरेस्ट मॉड16" को प्राथमिकता दी गई है. ज़्यादा जानकारी के लिए, SCALER_STREAM_CONFIGURATION_MAP देखें.

CameraX सेशन बनाता और मैनेज करता है. हालांकि, अपने कोड में इस्तेमाल के उदाहरण के आउटपुट पर, वापस मिलने वाली इमेज के साइज़ की हमेशा जांच करें और उस हिसाब से अडजस्ट करें.

रोटेशन

डिफ़ॉल्ट रूप से, कैमरे के रोटेशन को इस्तेमाल के उदाहरण बनाते समय, डिफ़ॉल्ट डिसप्ले के रोटेशन से मैच करने के लिए सेट किया जाता है. इस डिफ़ॉल्ट मामले में, CameraX आउटपुट जनरेट करता है, ताकि ऐप्लिकेशन उसी तरह की इमेज दिखा सके जैसी आपको झलक में दिखनी चाहिए. कई डिसप्ले डिवाइसों के साथ काम करने के लिए, रोटेशन को कस्टम वैल्यू में बदला जा सकता है. इसके लिए, इस्तेमाल के उदाहरण वाले ऑब्जेक्ट को कॉन्फ़िगर करते समय मौजूदा डिसप्ले ओरिएंटेशन को पास करें या ऑब्जेक्ट बनाने के बाद डाइनैमिक तौर पर ऐसा करें.

आपका ऐप्लिकेशन, कॉन्फ़िगरेशन सेटिंग का इस्तेमाल करके टारगेट रोटेशन सेट कर सकता है. इसके बाद, लाइफ़साइकल के चलने के दौरान भी, इस्तेमाल के उदाहरण वाले एपीआई (जैसे कि ImageAnalysis.setTargetRotation()) के तरीकों का इस्तेमाल करके, रोटेशन सेटिंग अपडेट की जा सकती हैं. इसका इस्तेमाल तब किया जा सकता है, जब ऐप्लिकेशन को पोर्ट्रेट मोड पर लॉक किया गया हो. इससे, डिवाइस के रोटेट होने पर, कॉन्फ़िगरेशन में कोई बदलाव नहीं होता. हालांकि, फ़ोटो या विश्लेषण के इस्तेमाल के उदाहरण में, डिवाइस के मौजूदा रोटेशन के बारे में जानकारी होनी चाहिए. उदाहरण के लिए, रोटेशन की जानकारी की ज़रूरत हो सकती है, ताकि चेहरे की पहचान करने के लिए, चेहरों को सही ओरिएंटेशन में रखा जा सके या फ़ोटो को लैंडस्केप या पोर्ट्रेट मोड में सेट किया जा सके.

कैप्चर की गई इमेज का डेटा, घुमाने की जानकारी के बिना सेव किया जा सकता है. Exif डेटा में, घुमाने की जानकारी होती है, ताकि गैलरी ऐप्लिकेशन, सेव करने के बाद इमेज को सही ओरिएंटेशन में दिखा सकें.

झलक के डेटा को सही ओरिएंटेशन में दिखाने के लिए, ट्रांसफ़ॉर्म बनाने के लिए Preview.PreviewOutput() से मिले मेटाडेटा के आउटपुट का इस्तेमाल किया जा सकता है.

यहां दिए गए कोड सैंपल में, ओरिएंटेशन इवेंट पर रोटेशन सेट करने का तरीका बताया गया है:

Kotlin

override fun onCreate() {
    val imageCapture = ImageCapture.Builder().build()

    val orientationEventListener = object : OrientationEventListener(this as Context) {
        override fun onOrientationChanged(orientation : Int) {
            // Monitors orientation values to determine the target rotation value
            val rotation : Int = when (orientation) {
                in 45..134 -> Surface.ROTATION_270
                in 135..224 -> Surface.ROTATION_180
                in 225..314 -> Surface.ROTATION_90
                else -> Surface.ROTATION_0
            }

            imageCapture.targetRotation = rotation
        }
    }
    orientationEventListener.enable()
}

Java

@Override
public void onCreate() {
    ImageCapture imageCapture = new ImageCapture.Builder().build();

    OrientationEventListener orientationEventListener = new OrientationEventListener((Context)this) {
       @Override
       public void onOrientationChanged(int orientation) {
           int rotation;

           // Monitors orientation values to determine the target rotation value
           if (orientation >= 45 && orientation < 135) {
               rotation = Surface.ROTATION_270;
           } else if (orientation >= 135 && orientation < 225) {
               rotation = Surface.ROTATION_180;
           } else if (orientation >= 225 && orientation < 315) {
               rotation = Surface.ROTATION_90;
           } else {
               rotation = Surface.ROTATION_0;
           }

           imageCapture.setTargetRotation(rotation);
       }
    };

    orientationEventListener.enable();
}

सेट किए गए रोटेशन के आधार पर, इस्तेमाल का हर उदाहरण या तो इमेज डेटा को सीधे घुमाता है या बिना घुमाए गए इमेज डेटा के उपभोक्ताओं को रोटेशन मेटाडेटा देता है.

  • झलक: मेटाडेटा का आउटपुट इसलिए दिया जाता है, ताकि Preview.getTargetRotation() का इस्तेमाल करके, टारगेट रिज़ॉल्यूशन के रोटेशन के बारे में पता चल सके.
  • ImageAnalysis: मेटाडेटा आउटपुट इसलिए दिया जाता है, ताकि इमेज बफ़र के कोऑर्डिनेट, डिसप्ले कोऑर्डिनेट के हिसाब से जाने जा सकें.
  • ImageCapture: रोटेशन सेटिंग को नोट करने के लिए, इमेज के Exif मेटाडेटा, बफ़र या बफ़र और मेटाडेटा, दोनों में बदलाव किया जाता है. बदली गई वैल्यू, एचएएल को लागू करने के तरीके पर निर्भर करती है.

Crop rect

डिफ़ॉल्ट रूप से, क्रॉप रेक्टैंगल, फ़ुल बफ़र रेक्टैंगल होता है. इसे अपनी पसंद के मुताबिक बनाने के लिए, ViewPort और UseCaseGroup का इस्तेमाल करें. इस्तेमाल के उदाहरणों को ग्रुप में बांटकर और व्यूपोर्ट सेट करके, CameraX यह पक्का करता है कि ग्रुप में मौजूद सभी इस्तेमाल के उदाहरणों के काटे गए हिस्से, कैमरा सेंसर में एक ही जगह पर हों.

नीचे दिया गया कोड स्निपेट, इन दो क्लास के इस्तेमाल का तरीका बताता है:

Kotlin

val viewPort =  ViewPort.Builder(Rational(width, height), display.rotation).build()
val useCaseGroup = UseCaseGroup.Builder()
    .addUseCase(preview)
    .addUseCase(imageAnalysis)
    .addUseCase(imageCapture)
    .setViewPort(viewPort)
    .build()
cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, useCaseGroup)

Java

ViewPort viewPort = new ViewPort.Builder(
         new Rational(width, height),
         getDisplay().getRotation()).build();
UseCaseGroup useCaseGroup = new UseCaseGroup.Builder()
    .addUseCase(preview)
    .addUseCase(imageAnalysis)
    .addUseCase(imageCapture)
    .setViewPort(viewPort)
    .build();
cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, useCaseGroup);

ViewPort, असली उपयोगकर्ताओं को दिखने वाले बफ़र रेक्ट के बारे में बताता है. इसके बाद, CameraX, व्यूपोर्ट की प्रॉपर्टी और अटैच किए गए इस्तेमाल के उदाहरणों के आधार पर, काटे जाने वाले सबसे बड़े बजट को कैलकुलेट करता है. आम तौर पर, WYSIWYG इफ़ेक्ट पाने के लिए, प्रीव्यू के इस्तेमाल के उदाहरण के आधार पर व्यूपोर्ट को कॉन्फ़िगर किया जा सकता है. व्यूपोर्ट पाने का एक आसान तरीका है, PreviewView का इस्तेमाल करना.

नीचे दिए गए कोड स्निपेट में, ViewPort ऑब्जेक्ट पाने का तरीका बताया गया है:

Kotlin

val viewport = findViewById<PreviewView>(R.id.preview_view).viewPort

Java

ViewPort viewPort = ((PreviewView)findViewById(R.id.preview_view)).getViewPort();

पिछले उदाहरण में, ऐप्लिकेशन को ImageAnalysis और ImageCapture से जो डेटा मिलता है वह वही होता है जो PreviewView में असली उपयोगकर्ता को दिखता है. ऐसा तब होता है, जब PreviewView का स्केल टाइप डिफ़ॉल्ट तौर पर FILL_CENTER पर सेट हो. आउटपुट बफ़र में काटने के लिए चुने गए हिस्से और घुमाने की सुविधा लागू करने के बाद, सभी इस्तेमाल के उदाहरणों की इमेज एक जैसी होती है. हालांकि, हो सकता है कि उनका रिज़ॉल्यूशन अलग-अलग हो. ट्रांसफ़ॉर्मेशन की जानकारी को लागू करने के तरीके के बारे में ज़्यादा जानने के लिए, आउटपुट को ट्रांसफ़ॉर्म करना लेख पढ़ें.

कैमरा चुनना

CameraX, आपके ऐप्लिकेशन की ज़रूरतों और इस्तेमाल के उदाहरणों के लिए, अपने-आप सबसे अच्छा कैमरा डिवाइस चुनता है. अगर आपको आपके लिए चुने गए डिवाइस के बजाय किसी दूसरे डिवाइस का इस्तेमाल करना है, तो आपके पास ये विकल्प हैं:

यहां दिए गए कोड सैंपल में, डिवाइस चुनने पर असर डालने के लिए CameraSelector बनाने का तरीका बताया गया है:

Kotlin

fun selectExternalOrBestCamera(provider: ProcessCameraProvider):CameraSelector? {
   val cam2Infos = provider.availableCameraInfos.map {
       Camera2CameraInfo.from(it)
   }.sortedByDescending {
       // HARDWARE_LEVEL is Int type, with the order of:
       // LEGACY < LIMITED < FULL < LEVEL_3 < EXTERNAL
       it.getCameraCharacteristic(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)
   }

   return when {
       cam2Infos.isNotEmpty() -> {
           CameraSelector.Builder()
               .addCameraFilter {
                   it.filter { camInfo ->
                       // cam2Infos[0] is either EXTERNAL or best built-in camera
                       val thisCamId = Camera2CameraInfo.from(camInfo).cameraId
                       thisCamId == cam2Infos[0].cameraId
                   }
               }.build()
       }
       else -> null
    }
}

// create a CameraSelector for the USB camera (or highest level internal camera)
val selector = selectExternalOrBestCamera(processCameraProvider)
processCameraProvider.bindToLifecycle(this, selector, preview, analysis)

एक साथ कई कैमरे चुनना

CameraX 1.3 और इसके बाद के वर्शन में, एक साथ कई कैमरे भी चुने जा सकते हैं. उदाहरण के लिए, एक साथ दोनों कैमरे से फ़ोटो लेने या वीडियो रिकॉर्ड करने के लिए, उन्हें एक साथ इस्तेमाल किया जा सकता है.

समवर्ती कैमरा सुविधा का उपयोग करते समय, डिवाइस में एक ही समय पर अलग-अलग लेंस वाले दो कैमरे या एक ही समय पर दो पीछे वाले कैमरे काम कर सकते है. यहां दिए गए कोड ब्लॉक में, bindToLifecycle को कॉल करते समय दो कैमरे सेट करने का तरीका बताया गया है. साथ ही, ConcurrentCamera ऑब्जेक्ट से दोनों कैमरे ऑब्जेक्ट पाने का तरीका भी बताया गया है.

Kotlin

// Build ConcurrentCameraConfig
val primary = ConcurrentCamera.SingleCameraConfig(
    primaryCameraSelector,
    useCaseGroup,
    lifecycleOwner
)

val secondary = ConcurrentCamera.SingleCameraConfig(
    secondaryCameraSelector,
    useCaseGroup,
    lifecycleOwner
)

val concurrentCamera = cameraProvider.bindToLifecycle(
    listOf(primary, secondary)
)

val primaryCamera = concurrentCamera.cameras[0]
val secondaryCamera = concurrentCamera.cameras[1]

Java

// Build ConcurrentCameraConfig
SingleCameraConfig primary = new SingleCameraConfig(
    primaryCameraSelector,
    useCaseGroup,
    lifecycleOwner
);

SingleCameraConfig secondary = new SingleCameraConfig(
    primaryCameraSelector,
    useCaseGroup,
    lifecycleOwner
);

ConcurrentCamera concurrentCamera =  
    mCameraProvider.bindToLifecycle(Arrays.asList(primary, secondary));

Camera primaryCamera = concurrentCamera.getCameras().get(0);
Camera secondaryCamera = concurrentCamera.getCameras().get(1);

कैमरे का रिज़ॉल्यूशन

आपके पास यह चुनने का विकल्प होता है कि CameraX, डिवाइस की सुविधाओं, डिवाइस पर काम करने वाले हार्डवेयर लेवल, इस्तेमाल के उदाहरण, और दिए गए आसपेक्ट रेशियो के आधार पर इमेज का रिज़ॉल्यूशन सेट करे. इसके अलावा, इस्तेमाल के उन उदाहरणों में कोई खास टारगेट रिज़ॉल्यूशन या आसपेक्ट रेशियो सेट किया जा सकता है जो उस कॉन्फ़िगरेशन के साथ काम करते हैं.

अपने-आप रिज़ॉल्यूशन तय होना

CameraX, cameraProcessProvider.bindToLifecycle() में बताए गए इस्तेमाल के उदाहरणों के आधार पर, सबसे अच्छे रिज़ॉल्यूशन की सेटिंग अपने-आप तय कर सकता है. जब भी हो सके, एक ही bindToLifecycle() कॉल में एक ही सेशन में एक साथ चलने के लिए, इस्तेमाल के सभी उदाहरणों की जानकारी दें. CameraX, इस्तेमाल के उदाहरणों के सेट के आधार पर रिज़ॉल्यूशन तय करता है. ऐसा डिवाइस के साथ काम करने वाले हार्डवेयर लेवल के आधार पर और डिवाइस के खास वैरियंस (जहां डिवाइस, स्ट्रीम कॉन्फ़िगरेशन उपलब्ध हैं या नहीं) को ध्यान में रखकर किया जाता है. इसका मकसद ऐप्लिकेशन को कई तरह के डिवाइस पर चलने देना है, जिससे डिवाइस के लिए खास कोड पाथ कम से कम हों.

इमेज कैप्चर करने और इमेज का विश्लेषण करने के उदाहरणों के लिए, डिफ़ॉल्ट आसपेक्ट रेशियो 4:3 होता है.

इस्तेमाल के उदाहरणों में आसपेक्ट रेशियो को कॉन्फ़िगर किया जा सकता है, ताकि ऐप्लिकेशन, यूज़र इंटरफ़ेस (यूआई) डिज़ाइन के आधार पर अपनी पसंद का आसपेक्ट रेशियो तय कर सके. CameraX आउटपुट, अनुरोध किए गए आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) के हिसाब से होता है. यह आउटपुट डिवाइस के हिसाब से काम करता है. अगर एग्ज़ैक्ट मैच वाला कोई रिज़ॉल्यूशन काम नहीं करता है, तो सबसे ज़्यादा शर्तें पूरी करने वाला रिज़ॉल्यूशन चुना जाता है. इस तरह, ऐप्लिकेशन यह तय करता है कि कैमरा, ऐप्लिकेशन में किस तरह दिखेगा. साथ ही, CameraX अलग-अलग डिवाइसों पर इसके हिसाब से सबसे अच्छी कैमरा रिज़ॉल्यूशन सेटिंग तय करता है.

उदाहरण के लिए, कोई ऐप्लिकेशन इनमें से कोई भी काम कर सकता है:

  • इस्तेमाल के उदाहरण के लिए, 4:3 या 16:9 का टारगेट रिज़ॉल्यूशन तय करना
  • कोई कस्टम रिज़ॉल्यूशन तय करें, जिसे CameraX मिलता-जुलता रिज़ॉल्यूशन ढूंढने की कोशिश करता है
  • ImageCapture के लिए काटने का आसपेक्ट रेशियो तय करना

CameraX, Camera2 में मौजूद सतह के रिज़ॉल्यूशन को अपने-आप चुनता है. नीचे दी गई टेबल में रिज़ॉल्यूशन दिखाए गए हैं:

इस्तेमाल का उदाहरण इंटरनल प्लैटफ़ॉर्म का रिज़ॉल्यूशन आउटपुट डेटा का रिज़ॉल्यूशन
झलक देखें आसपेक्ट रेशियो: यह रिज़ॉल्यूशन, सेटिंग के टारगेट के हिसाब से सबसे सही होता है. डिवाइस के अंदर मौजूद रिज़ॉल्यूशन. मेटाडेटा, टारगेट आसपेक्ट रेशियो के लिए व्यू को काटने, स्केल करने, और घुमाने की सुविधा देता है.
डिफ़ॉल्ट रिज़ॉल्यूशन: झलक का सबसे ज़्यादा रिज़ॉल्यूशन या डिवाइस के लिए सबसे ज़्यादा रिज़ॉल्यूशन, जो झलक के आसपेक्ट रेशियो से मेल खाता हो.
ज़्यादा से ज़्यादा रिज़ॉल्यूशन: झलक का साइज़, जो डिवाइस की स्क्रीन के रिज़ॉल्यूशन या 1080p (1920x1080) में से, जो भी छोटा हो उससे मैच करने वाला सबसे अच्छा साइज़ होता है.
इमेज का विश्लेषण आसपेक्ट रेशियो: यह रेज़ॉल्यूशन, सेटिंग के टारगेट के हिसाब से सबसे सही होता है. अंदरूनी सरफ़ेस रिज़ॉल्यूशन.
डिफ़ॉल्ट रिज़ॉल्यूशन: टारगेट रिज़ॉल्यूशन की डिफ़ॉल्ट सेटिंग, 640x480 है. टारगेट रिज़ॉल्यूशन और उससे जुड़े आसपेक्ट रेशियो, दोनों को अडजस्ट करने पर, सबसे अच्छा रिज़ॉल्यूशन मिलता है.
ज़्यादा से ज़्यादा रिज़ॉल्यूशन: कैमरा डिवाइस का ज़्यादा से ज़्यादा आउटपुट रिज़ॉल्यूशन, YUV_420_888 फ़ॉर्मैट में होता है. इसे StreamConfigurationMap.getOutputSizes() से हासिल किया जाता है. टारगेट रिज़ॉल्यूशन, डिफ़ॉल्ट रूप से 640x480 पर सेट होता है. इसलिए, अगर आपको 640x480 से बड़ा रिज़ॉल्यूशन चाहिए, तो आपको setTargetResolution() और setTargetAspectRatio() का इस्तेमाल करना होगा.
इमेज कैप्चर करने की सुविधा आसपेक्ट रेशियो: सेटिंग के हिसाब से सबसे सही आसपेक्ट रेशियो. अंदरूनी सरफ़ेस रिज़ॉल्यूशन.
डिफ़ॉल्ट रिज़ॉल्यूशन: उपलब्ध सबसे ज़्यादा रिज़ॉल्यूशन या डिवाइस के लिए सबसे ज़्यादा रिज़ॉल्यूशन, जो ImageCapture के आसपेक्ट रेशियो से मेल खाता हो.
ज़्यादा से ज़्यादा रिज़ॉल्यूशन: कैमरा डिवाइस का ज़्यादा से ज़्यादा आउटपुट रिज़ॉल्यूशन, जो JPEG फ़ॉर्मैट में होता है. इसे वापस पाने के लिए, StreamConfigurationMap.getOutputSizes() का इस्तेमाल करें.

रिज़ॉल्यूशन तय करना

setTargetResolution(Size resolution) तरीके का इस्तेमाल करके, इस्तेमाल के उदाहरण बनाते समय खास रिज़ॉल्यूशन सेट किए जा सकते हैं. इस बारे में यहां दिए गए कोड के सैंपल में बताया गया है:

Kotlin

val imageAnalysis = ImageAnalysis.Builder()
    .setTargetResolution(Size(1280, 720))
    .build()

Java

ImageAnalysis imageAnalysis =
  new ImageAnalysis.Builder()
    .setTargetResolution(new Size(1280, 720))
    .build();

इस्तेमाल के एक ही उदाहरण में, टारगेट आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) और टारगेट रिज़ॉल्यूशन, दोनों को सेट नहीं किया जा सकता. ऐसा करने पर, कॉन्फ़िगरेशन ऑब्जेक्ट बनाते समय IllegalArgumentException दिखता है.

टारगेट रोटेशन के हिसाब से काम करने वाले साइज़ को घुमाने के बाद, कोऑर्डिनेट फ़्रेम में रिज़ॉल्यूशन Size दिखाएं. उदाहरण के लिए, पोर्ट्रेट नेचुरल ओरिएंटेशन में नेचुरल टारगेट रोटेशन वाला डिवाइस, पोर्ट्रेट इमेज का अनुरोध कर सकता है. इसके लिए, वह 480x640 का रिज़ॉल्यूशन तय कर सकता है. वहीं, उसी डिवाइस को 90 डिग्री घुमाकर, लैंडस्केप ओरिएंटेशन को टारगेट किया जा सकता है. इसके लिए, वह 640x480 का रिज़ॉल्यूशन तय कर सकता है.

टारगेट रिज़ॉल्यूशन, इमेज रिज़ॉल्यूशन के लिए कम से कम सीमा तय करने की कोशिश करता है. इमेज का असल रिज़ॉल्यूशन, उपलब्ध रिज़ॉल्यूशन में से सबसे करीब का ऐसा रिज़ॉल्यूशन होता है जो टारगेट रिज़ॉल्यूशन से छोटा न हो. यह रिज़ॉल्यूशन, कैमरे के लागू होने के तरीके से तय होता है.

हालांकि, अगर ऐसा कोई रिज़ॉल्यूशन मौजूद नहीं है जो टारगेट रिज़ॉल्यूशन के बराबर या उससे ज़्यादा हो, तो वह सबसे नज़दीकी उपलब्ध रिज़ॉल्यूशन चुना जाता है जो टारगेट रिज़ॉल्यूशन से कम होता है. दिए गए Size के आसपेक्ट रेशियो वाले रिज़ॉल्यूशन को, अलग-अलग आसपेक्ट रेशियो वाले रिज़ॉल्यूशन से ज़्यादा प्राथमिकता दी जाती है.

CameraX, अनुरोधों के आधार पर सबसे सही रिज़ॉल्यूशन लागू करता है. अगर मुख्य ज़रूरत आसपेक्ट रेशियो को पूरा करना है, तो सिर्फ़ setTargetAspectRatio की वैल्यू दें. इसके बाद, CameraX डिवाइस के हिसाब से सही रिज़ॉल्यूशन तय करेगा. अगर ऐप्लिकेशन की मुख्य ज़रूरत, इमेज प्रोसेसिंग को ज़्यादा बेहतर बनाने के लिए रिज़ॉल्यूशन तय करना है, तो setTargetResolution(Size resolution) का इस्तेमाल करें. उदाहरण के लिए, डिवाइस की प्रोसेसिंग क्षमता के आधार पर छोटी या मीडियम साइज़ की इमेज.

अगर आपके ऐप्लिकेशन के लिए कोई खास रिज़ॉल्यूशन ज़रूरी है, तो createCaptureSession() में दी गई टेबल देखें. इससे आपको यह पता चलेगा कि हर हार्डवेयर लेवल पर, ज़्यादा से ज़्यादा कौनसे रिज़ॉल्यूशन काम करते हैं. मौजूदा डिवाइस पर काम करने वाले रिज़ॉल्यूशन देखने के लिए, StreamConfigurationMap.getOutputSizes(int) देखें.

अगर आपका ऐप्लिकेशन Android 10 या इसके बाद के वर्शन पर चल रहा है, तो किसी SessionConfiguration की पुष्टि करने के लिए, isSessionConfigurationSupported() का इस्तेमाल किया जा सकता है.

कैमरे के आउटपुट को कंट्रोल करना

CameraX, हर इस्तेमाल के उदाहरण के लिए ज़रूरत के मुताबिक कैमरे के आउटपुट को कॉन्फ़िगर करने की सुविधा देता है. साथ ही, सभी इस्तेमाल के उदाहरणों के लिए कैमरे के सामान्य कामों के साथ काम करने के लिए, ये इंटरफ़ेस भी लागू करता है:

  • CameraControl की मदद से, कैमरे की सामान्य सुविधाओं को कॉन्फ़िगर किया जा सकता है.
  • CameraInfo की मदद से, कैमरे की सामान्य सुविधाओं की स्थिति के बारे में जानकारी पाई जा सकती है.

CameraControl के साथ काम करने वाली कैमरे की सुविधाएं:

  • Zoom
  • टॉर्च
  • फ़ोकस और मीटरिंग (टैप-टू-फ़ोकस)
  • एक्सपोज़र कंपंसेशन

CameraControl और CameraInfo के इंस्टेंस पाना

ProcessCameraProvider.bindToLifecycle() से मिले Camera ऑब्जेक्ट का इस्तेमाल करके, CameraControl और CameraInfo के इंस्टेंस वापस पाएं. उदाहरण के लिए, यहां दिया गया कोड देखें:

Kotlin

val camera = processCameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview)

// For performing operations that affect all outputs.
val cameraControl = camera.cameraControl
// For querying information and states.
val cameraInfo = camera.cameraInfo

Java

Camera camera = processCameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview)

// For performing operations that affect all outputs.
CameraControl cameraControl = camera.getCameraControl()
// For querying information and states.
CameraInfo cameraInfo = camera.getCameraInfo()

उदाहरण के लिए, bindToLifecycle() को कॉल करने के बाद, ज़ूम और अन्य CameraControl ऑपरेशन सबमिट किए जा सकते हैं. कैमरा इंस्टेंस को बाइंड करने के लिए इस्तेमाल की गई गतिविधि को बंद करने या बंद करने के बाद, CameraControl कार्रवाइयां लागू नहीं कर सकता है और फ़ेल हो गया ListenableFuture दिखाता है.

Zoom

CameraControl में ज़ूम लेवल बदलने के दो तरीके हैं:

  • setZoomRatio() ज़ूम रेशियो के हिसाब से ज़ूम सेट करता है.

    आसपेक्ट रेशियो, CameraInfo.getZoomState().getValue().getMinZoomRatio() और CameraInfo.getZoomState().getValue().getMaxZoomRatio() के बीच होना चाहिए. ऐसा न होने पर, फ़ंक्शन ListenableFuture दिखाता है.

  • setLinearZoom() मौजूदा ज़ूम को 0 से 1.0 के बीच के लीनियर ज़ूम वैल्यू पर सेट करता है.

    लीनियर ज़ूम का फ़ायदा यह है कि ज़ूम में होने वाले बदलावों के साथ फ़ील्ड ऑफ़ व्यू (एफ़ओवी) का स्केल भी बदल जाता है. इसलिए, इसे Slider व्यू के साथ इस्तेमाल करना सबसे सही रहेगा.

CameraInfo.getZoomState() यह फ़ंक्शन, ज़ूम की मौजूदा स्थिति का LiveData दिखाता है. कैमरा शुरू होने या setZoomRatio() या setLinearZoom() का इस्तेमाल करके ज़ूम लेवल सेट होने पर, वैल्यू बदल जाती है. किसी भी तरीके को कॉल करने से, बैकिंग ZoomState.getZoomRatio() और ZoomState.getLinearZoom() वैल्यू सेट हो जाती हैं. अगर आपको स्लाइडर के साथ ज़ूम रेशियो टेक्स्ट दिखाना है, तो यह सुविधा आपके लिए मददगार हो सकती है. कन्वर्ज़न किए बिना, दोनों को अपडेट करने के लिए, ZoomState LiveData को देखें.

दोनों एपीआई से मिलने वाले ListenableFuture से, ऐप्लिकेशन को सूचना देने का विकल्प मिलता है. यह सूचना तब दी जाती है, जब तय की गई ज़ूम वैल्यू के साथ बार-बार किए जाने वाले अनुरोध को पूरा कर लिया जाता है. इसके अलावा, अगर पिछली कार्रवाई के चालू रहने के दौरान कोई नई ज़ूम वैल्यू सेट की जाती है, तो ज़ूम करने की पिछली कार्रवाई का ListenableFuture तुरंत काम करना बंद कर देता है.

टॉर्च

CameraControl.enableTorch(boolean) इससे टॉर्च (जिसे फ़्लैशलाइट भी कहा जाता है) चालू या बंद होती है.

टॉर्च की मौजूदा स्थिति के बारे में क्वेरी करने के लिए, CameraInfo.getTorchState() का इस्तेमाल किया जा सकता है. टॉर्च उपलब्ध है या नहीं, यह पता लगाने के लिए CameraInfo.hasFlashUnit() के ज़रिए मिली वैल्यू देखी जा सकती है. अगर ऐसा नहीं है, तो CameraControl.enableTorch(boolean) को कॉल करने पर, ListenableFuture तुरंत 'काम नहीं किया' नतीजे के साथ पूरा हो जाता है और टॉर्च की स्थिति को TorchState.OFF पर सेट कर देता है.

टॉर्च चालू होने पर, फ़ोटो और वीडियो कैप्चर करने के दौरान यह चालू रहता है. भले ही, flashMode की सेटिंग कुछ भी हो. ImageCapture में मौजूद flashMode सिर्फ़ तब काम करता है, जब टॉर्च बंद हो.

फ़ोकस और मीटरिंग

CameraControl.startFocusAndMetering() दिए गए FocusMeteringAction के आधार पर AF/AE/AWB मीटरिंग क्षेत्र सेट करके, ऑटोफ़ोकस और एक्सपोज़र मीटरिंग को ट्रिगर करता है. इसका इस्तेमाल अक्सर कई कैमरा ऐप्लिकेशन में, “फ़ोकस करने के लिए टैप करें” सुविधा को लागू करने के लिए किया जाता है.

MeteringPoint

शुरू करने के लिए, MeteringPointFactory.createPoint(float x, float y, float size) का इस्तेमाल करके MeteringPoint बनाएं. MeteringPoint, कैमरे पर मौजूद किसी एक बिंदु को दिखाता है Surface. इसे सामान्य फ़ॉर्मैट में सेव किया जाता है, ताकि इसे एएफ़/एई/एडब्ल्यूबी क्षेत्रों की जानकारी देने के लिए, आसानी से सेंसर निर्देशांक में बदला जा सके.

MeteringPoint का साइज़ 0 से 1 तक होता है. इसका डिफ़ॉल्ट साइज़ 0.15f होता है. MeteringPointFactory.createPoint(float x, float y, float size) को कॉल करते समय, CameraX दिए गए size के लिए, (x, y) के बीच में एक रेक्टैंगल क्षेत्र बनाता है.

यह कोड, MeteringPoint बनाने का तरीका बताता है:

Kotlin

// Use PreviewView.getMeteringPointFactory if PreviewView is used for preview.
previewView.setOnTouchListener((view, motionEvent) ->  {
val meteringPoint = previewView.meteringPointFactory
    .createPoint(motionEvent.x, motionEvent.y)

}

// Use DisplayOrientedMeteringPointFactory if SurfaceView / TextureView is used for
// preview. Please note that if the preview is scaled or cropped in the View,
// it’s the application's responsibility to transform the coordinates properly
// so that the width and height of this factory represents the full Preview FOV.
// And the (x,y) passed to create MeteringPoint might need to be adjusted with
// the offsets.
val meteringPointFactory = DisplayOrientedMeteringPointFactory(
     surfaceView.display,
     camera.cameraInfo,
     surfaceView.width,
     surfaceView.height
)

// Use SurfaceOrientedMeteringPointFactory if the point is specified in
// ImageAnalysis ImageProxy.
val meteringPointFactory = SurfaceOrientedMeteringPointFactory(
     imageWidth,
     imageHeight,
     imageAnalysis)

startFocusAndMetering और FocusMeteringAction

startFocusAndMetering() शुरू करने के लिए, ऐप्लिकेशन को FocusMeteringAction बनाना होगा, जिसमें FLAG_AF,FLAG_AE,FLAG_AWB के वैकल्पिक मीटरिंग मोड के साथ एक या उससे ज़्यादा MeteringPoints शामिल हों. यहां दिए गए कोड में इसका इस्तेमाल दिखाया गया है:

Kotlin

val meteringPoint1 = meteringPointFactory.createPoint(x1, x1)
val meteringPoint2 = meteringPointFactory.createPoint(x2, y2)
val action = FocusMeteringAction.Builder(meteringPoint1) // default AF|AE|AWB
      // Optionally add meteringPoint2 for AF/AE.
      .addPoint(meteringPoint2, FLAG_AF | FLAG_AE)
      // The action is canceled in 3 seconds (if not set, default is 5s).
      .setAutoCancelDuration(3, TimeUnit.SECONDS)
      .build()

val result = cameraControl.startFocusAndMetering(action)
// Adds listener to the ListenableFuture if you need to know the focusMetering result.
result.addListener({
   // result.get().isFocusSuccessful returns if the auto focus is successful or not.
}, ContextCompat.getMainExecutor(this)

जैसा कि पिछले कोड में दिखाया गया है, startFocusAndMetering() में FocusMeteringAction लिया जाता है. इसमें सिर्फ़ AF/AE/AWB मीटरिंग वाले क्षेत्रों के लिए एक MeteringPoint और सिर्फ़ AF और AE के लिए दूसरा मीटरिंगपॉइंट शामिल होता है.

CameraX, इसे अंदरूनी तौर पर Camera2 MeteringRectangles में बदल देता है और कैप्चर करने के अनुरोध के लिए, उससे जुड़े CONTROL_AF_REGIONS / CONTROL_AE_REGIONS / CONTROL_AWB_REGIONS पैरामीटर सेट करता है.

हर डिवाइस पर AF/AE/AWB और एक से ज़्यादा क्षेत्रों के लिए ऑटोमैटिक फ़ोकस की सुविधा काम नहीं करती. इसलिए, CameraX FocusMeteringAction को बेहतर तरीके से लागू करने की कोशिश करता है. पॉइंट जोड़े जाने के क्रम में, CameraX उतने ही मीटरिंगपॉइंट का इस्तेमाल करता है जितने की अनुमति है. तय सीमा से ज़्यादा जोड़े गए सभी MeteringPoints को अनदेखा कर दिया जाता है. उदाहरण के लिए, अगर FocusMeteringAction को किसी ऐसे प्लैटफ़ॉर्म पर तीन मीटरिंगपॉइंट के साथ सप्लाई किया गया है, जो सिर्फ़ दो के साथ काम करता है, तो सिर्फ़ पहले दो मीटरिंगपॉइंट का ही इस्तेमाल किया जाएगा. आखिरी MeteringPoint को CameraX ने अनदेखा कर दिया है.

एक्सपोज़र कंपंसेशन

एक्सपोज़र कंपेसेशन तब काम आता है, जब ऐप्लिकेशन को ऑटो एक्सपोज़र (एई) के आउटपुट नतीजे के अलावा, एक्सपोज़र वैल्यू (ईवी) को बेहतर बनाना हो. एक्सपोज़र मुआवज़े की वैल्यू को इस तरह से जोड़ा जाता है कि इमेज की मौजूदा स्थितियों के लिए, ज़रूरी एक्सपोज़र का पता लगाया जाता है:

Exposure = ExposureCompensationIndex * ExposureCompensationStep

CameraX, एक्सपोज़र कम्पेंसेशन को इंडेक्स वैल्यू के तौर पर सेट करने के लिए, Camera.CameraControl.setExposureCompensationIndex() फ़ंक्शन उपलब्ध कराता है.

इंडेक्स की पॉज़िटिव वैल्यू से इमेज ज़्यादा चमकदार हो जाती है, जबकि नेगेटिव वैल्यू से इमेज धीमी हो जाती है. ऐप्लिकेशन, अगले सेक्शन में बताए गए CameraInfo.ExposureState.exposureCompensationRange() का इस्तेमाल करके, काम करने वाली रेंज के बारे में क्वेरी कर सकते हैं. अगर वैल्यू का इस्तेमाल किया जा सकता है, तो कैप्चर अनुरोध में वैल्यू के चालू होने पर, दिखाया गया ListenableFuture पूरा हो जाता है. अगर दिया गया इंडेक्स, इस्तेमाल की जा सकने वाली रेंज से बाहर है, तो setExposureCompensationIndex() की वजह से दिखाया गया ListenableFuture, तुरंत गड़बड़ी का नतीजा दिखाकर पूरा हो जाता है.

CameraX सिर्फ़ हाल ही में किए गए setExposureCompensationIndex() अनुरोध को सेव रखता है. साथ ही, पिछले अनुरोध के लागू होने से पहले फ़ंक्शन को कई बार कॉल करने पर, उसे रद्द कर दिया जाता है.

नीचे दिया गया स्निपेट एक एक्सपोज़र कंपंसेशन इंडेक्स सेट करता है. साथ ही, एक्सपोज़र में बदलाव का अनुरोध पूरा होने के बाद एक कॉलबैक रजिस्टर करता है:

Kotlin

camera.cameraControl.setExposureCompensationIndex(exposureCompensationIndex)
   .addListener({
      // Get the current exposure compensation index, it might be
      // different from the asked value in case this request was
      // canceled by a newer setting request.
      val currentExposureIndex = camera.cameraInfo.exposureState.exposureCompensationIndex
      
   }, mainExecutor)
  • Camera.CameraInfo.getExposureState(), मौजूदा ExposureState को वापस लाता है. इसमें ये शामिल हैं:

    • एक्सपोज़र कंपंसेशन कंट्रोल की सपोर्टेबिलिटी.
    • एक्सपोज़र कंपंसेशन का मौजूदा इंडेक्स.
    • एक्सपोज़र कंपंसेशन इंडेक्स की रेंज.
    • एक्सपोज़र कंपंसेशन की वैल्यू का हिसाब लगाने के लिए, एक्सपोज़र कंपंसेशन का यह चरण इस्तेमाल किया जाता है.

उदाहरण के लिए, यह कोड ExposureState की मौजूदा वैल्यू SeekBar के साथ एक्सपोज़र की सेटिंग को शुरू करता है:

Kotlin

val exposureState = camera.cameraInfo.exposureState
binding.seekBar.apply {
   isEnabled = exposureState.isExposureCompensationSupported
   max = exposureState.exposureCompensationRange.upper
   min = exposureState.exposureCompensationRange.lower
   progress = exposureState.exposureCompensationIndex
}

अन्य संसाधन

CameraX के बारे में ज़्यादा जानने के लिए, यहां दिए गए अन्य संसाधन देखें.

कोडलैब (कोड बनाना सीखना)

  • CameraX का इस्तेमाल शुरू करना
  • कोड का सैंपल

  • CameraX ऐप्लिकेशन के सैंपल
  • डेवलपर कम्यूनिटी

    Android CameraX के बारे में चर्चा करने वाला ग्रुप