आउटपुट स्ट्रीम, उन्हें काटना, और ज़ूम करना

आउटपुट स्ट्रीम

कैमरा सबसिस्टम, सभी रिज़ॉल्यूशन और आउटपुट फ़ॉर्मैट के लिए, सिर्फ़ ANativeWindow पर आधारित पाइपलाइन पर काम करता है. एक ही फ़्रेम को कई टारगेट पर भेजने के लिए, एक साथ कई स्ट्रीम कॉन्फ़िगर की जा सकती हैं. जैसे, जीपीयू, वीडियो एन्कोडर, RenderScript या ऐप्लिकेशन के दिखने वाले बफ़र (आरएडब्ल्यू बेयर, प्रोसेस किए गए YUV बफ़र या JPEG में एन्कोड किए गए बफ़र).

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

साथ काम करने वाले हार्डवेयर लेवल के हिसाब से, गारंटी वाले स्ट्रीम के आउटपुट कॉम्बिनेशन के बारे में ज़्यादा जानकारी के लिए, createCaptureSession() देखें.

काट-छांट करना

पूरे पिक्सल ऐरे को काटने के लिए, ANDROID_SCALER_CROP_REGION सेटिंग का इस्तेमाल किया जाता है. ऐसा डिजिटल ज़ूम और ऐसे अन्य इस्तेमाल के उदाहरणों के लिए किया जाता है जहां कम एफ़ओवी (फ़ील्ड ऑफ़ व्यू) की ज़रूरत होती है. यह हर अनुरोध के हिसाब से सेट की जाती है और हर अनुरोध के हिसाब से बदल सकती है. यह सेटिंग, डिजिटल ज़ूम को आसानी से लागू करने के लिए ज़रूरी है.

क्षेत्र को आयत (x, y, चौड़ाई, ऊंचाई) के तौर पर दिखाया जाता है. इसमें (x, y) आयत के सबसे ऊपर बाएं कोने के बारे में बताता है. रेक्टैंगल को सेंसर ऐक्टिव पिक्सल अरे के कोऑर्डिनेट सिस्टम पर बताया जाता है. इसमें (0, 0), ऐक्टिव पिक्सल अरे का सबसे ऊपर बाईं ओर मौजूद पिक्सल होता है. इसलिए, चौड़ाई और ऊंचाई ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY स्टैटिक जानकारी फ़ील्ड में रिपोर्ट किए गए डाइमेंशन से ज़्यादा नहीं हो सकती. HAL, ANDROID_SCALER_MAX_DIGITAL_ZOOM स्टैटिक जानकारी वाले फ़ील्ड के ज़रिए, कम से कम अनुमति वाली चौड़ाई और ऊंचाई की जानकारी देता है. इस फ़ील्ड से, ज़्यादा से ज़्यादा ज़ूम फ़ैक्टर के बारे में पता चलता है. इसलिए, इमेज के क्षेत्र की कम से कम चौड़ाई और ऊंचाई इस तरह है:

  {width, height} =
   { floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[0] /
       ANDROID_SCALER_MAX_DIGITAL_ZOOM),
     floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[1] /
       ANDROID_SCALER_MAX_DIGITAL_ZOOM) }

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

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

सभी मामलों में, स्ट्रीम का काटा गया हिस्सा, क्रॉप किए गए पूरे हिस्से के बीच में होना चाहिए. साथ ही, स्ट्रीम को क्रॉप किए गए पूरे हिस्से के हिसाब से, सिर्फ़ हॉरिज़ॉन्टल या वर्टिकल में काटा जा सकता है, दोनों में नहीं.

उदाहरण के लिए, अगर दो स्ट्रीम तय की गई हैं, तो 640x480 स्ट्रीम (4:3 आसपेक्ट) और एक 1280x720 स्ट्रीम (16:9 आसपेक्ट), नीचे दिए गए उदाहरण में, काल्पनिक 3 एमपी (2000 x 1500 पिक्सल ऐरे) सेंसर पर, काटे गए कुछ सैंपल क्षेत्रों के लिए हर स्ट्रीम के लिए अनुमानित आउटपुट क्षेत्र दिखाए गए हैं.

काटा गया हिस्सा: (500, 375, 1000, 750) (4:3 आसपेक्ट रेशियो)
640x480 स्ट्रीम का काटा गया हिस्सा: (500, 375, 1000, 750) (काटे गए हिस्से के बराबर)
1280x720 स्ट्रीम का काटा गया हिस्सा: (500, 469, 1000, 562)

crop-region-43-ratio

पहली इमेज. 4:3 पक्षानुपात

काटा गया क्षेत्र: (500, 375, 1333, 750) (16:9 आसपेक्ट रेशियो या लंबाई-चौड़ाई का अनुपात)
640x480 स्ट्रीम क्रॉप: (666, 375, 1000, 750)
1280x720 स्ट्रीम क्रॉप: (500, 375, 750 से लेकर 1330 पिक्सल) क्षेत्र (500, 375, 750)

क्रॉप क्षेत्र-169-अनुपात

दूसरी इमेज. 16:9 का आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात)

काटा गया हिस्सा: (500, 375, 750, 750) (1:1 आसपेक्ट रेशियो)
640x480 स्ट्रीम का काटा गया हिस्सा: (500, 469, 750, 562)
1280x720 स्ट्रीम का काटा गया हिस्सा: (500, 543, 750, 414)

crop-region-11-ratio

तीसरी इमेज. 1:1 का आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात)

आखिरी उदाहरण, 480p वाली स्ट्रीम के बजाय 1024x1024 स्क्वेयर आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) वाली स्ट्रीम:
क्रॉप क्षेत्र: (500, 375, 1000, 750) (4:3 का आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात))
1024x1024 स्ट्रीम क्रॉप (625, 3
5, 780) 705, 375, 780)

क्रॉप-क्षेत्र-43-स्क्वेयर-अनुपात

चौथी इमेज. 4:3 आसपेक्ट रेशियो, स्क्वेयर

फिर से प्रोसेस करना

RAW Bayer डेटा को फिर से प्रोसेस करने की सुविधा से, रॉ इमेज फ़ाइलों के लिए अतिरिक्त सहायता मिलती है. इस सुविधा की मदद से, कैमरा पाइपलाइन पहले से कैप्चर किए गए RAW बफ़र और मेटाडेटा (पहले रिकॉर्ड किया गया एक पूरा फ़्रेम) को प्रोसेस कर पाती है. इससे, रेंडर किया गया नया YUV या JPEG आउटपुट जनरेट किया जा सकता है.

Zoom

Android 11 या इसके बाद के वर्शन वाले डिवाइसों पर, कोई ऐप्लिकेशन ANDROID_CONTROL_ZOOM_RATIO सेटिंग की मदद से कैमरे के ज़ूम (डिजिटल और ऑप्टिकल) का इस्तेमाल कर सकता है.

ज़ूम रेशियो को फ़्लोटिंग पॉइंट फ़ैक्टर के तौर पर परिभाषित किया जाता है. काट-छांट और ज़ूम करने के लिए ANDROID_SCALER_CROP_REGION का इस्तेमाल करने के बजाय, कोई ऐप्लिकेशन ज़ूम लेवल को कंट्रोल करने के लिए ANDROID_CONTROL_ZOOM_RATIO का इस्तेमाल कर सकता है. साथ ही, नेटिव कैमरा सेंसर से अलग आसपेक्ट रेशियो पाने के लिए, हॉरिज़ॉन्टल और वर्टिकल काट-छांट करने के लिए ANDROID_SCALER_CROP_REGION का इस्तेमाल कर सकता है.

मल्टी-कैमरा सिस्टम में, अलग-अलग फ़ोकल लेंथ वाले एक से ज़्यादा लेंस हो सकते हैं. साथ ही, उपयोगकर्ता लेंस के बीच स्विच करके ऑप्टिकल ज़ूम का इस्तेमाल कर सकता है. ANDROID_CONTROL_ZOOM_RATIO का इस्तेमाल करने से, इन स्थितियों में फ़ायदे मिलते हैं:

  • वाइड लेंस से टेलीफ़ोटो लेंस पर ज़ूम इन करना: फ़्लोटिंग पॉइंट रेशियो, ANDROID_SCALER_CROP_REGION की पूर्णांक वैल्यू की तुलना में ज़्यादा सटीक होता है.
  • वाइड लेंस से अल्ट्रावाइड लेंस पर ज़ूम आउट करने की सुविधा: ANDROID_CONTROL_ZOOM_RATIO पर ज़ूम-आउट (<1.0f) की सुविधा काम करती है, जबकि ANDROID_SCALER_CROP_REGION पर नहीं.

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

ज़ूम रेशियो: 2.0; मूल फ़ील्ड ऑफ़ व्यू का 1/4
काटा गया हिस्सा: (0, 0, 2000, 1500) (4:3 आसपेक्ट रेशियो)
640x480 स्ट्रीम का काटा गया हिस्सा: (0, 0, 2000, 1500) (काटे गए हिस्से के बराबर)
1280x720 स्ट्रीम का काटा गया हिस्सा: (0, 187, 2000, 1125)

zoom-ratio-2-crop-43

पांचवी इमेज. 2.0 ज़ूम, 4:3 आसपेक्ट रेशियो

ज़ूम रेशियो: 2.0; ओरिजनल फ़ील्ड ऑफ़ व्यू का 1/4
काटा गया हिस्सा: (0, 187, 2000, 1125) (16:9 आसपेक्ट रेशियो)
640x480 स्ट्रीम का काटा गया हिस्सा: (250, 187, 1500, 1125) (पाइलरबॉक्स किया गया)
1280x720 स्ट्रीम का काटा गया हिस्सा: (0, 187, 2000, 1125) (काटे गए हिस्से के बराबर)

zoom-ratio-2-crop-169

छठी इमेज. 2.0 ज़ूम, 16:9 आसपेक्ट रेशियो

ज़ूम रेशियो: 0.5; ओरिजनल फ़ील्ड ऑफ़ व्यू का चार गुना (वाइड लेंस से अल्ट्रा-वाइड लेंस पर स्विच किया गया)
काटा गया हिस्सा: (250, 0, 1500, 1500) (1:1 आसपेक्ट रेशियो)
640x480 स्ट्रीम का काटा गया हिस्सा: (250, 187, 1500, 1125) (लेटरबॉक्स किया गया)
1280x720 स्ट्रीम का काटा गया हिस्सा: (250, 328, 1500, 844) (लेटरबॉक्स किया गया)

images/zoom-ratio-0.5-crop-11

सातवीं इमेज. 0.5 ज़ूम, 1:1 आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात)

ऊपर दिए गए ग्राफ़ से पता चलता है कि काटे गए हिस्से के कोऑर्डिनेट सिस्टम को ज़ूम करने के बाद, फ़ील्ड ऑफ़ व्यू में बदल दिया जाता है. इसे इन डाइमेंशन वाले रेक्टैंगल से दिखाया जाता है: (0, 0, activeArrayWith, activeArrayHeight). यही बात, एई/एडब्ल्यूबी/एएफ़ के क्षेत्रों और चेहरों पर भी लागू होती है. निर्देशांक सिस्टम में किया गया यह बदलाव, intrinsicCalibration और lensShadingMap जैसे रैंडम ऐक्सेस मेमोरी (आरएडब्ल्यू) कैप्चर और उससे जुड़े मेटाडेटा पर लागू नहीं होता.

ऊपर दिए गए काल्पनिक उदाहरण का इस्तेमाल करके, और यह मानते हुए कि आउटपुट स्ट्रीम #1 (640x480) व्यूफ़ाइंडर स्ट्रीम है, 2.0x ज़ूम करने के लिए, इनमें से कोई एक तरीका अपनाया जा सकता है:

  • zoomRatio = 2.0, scaler.cropRegion = (0, 0, 2000, 1500)
  • zoomRatio = 1.0 (डिफ़ॉल्ट), scaler.cropRegion = (500, 375, 1000, 750)

अगर किसी ऐप्लिकेशन को android.control.aeRegions को व्यूफ़ाइंडर के फ़ील्ड ऑफ़ व्यू के सबसे ऊपर बाईं ओर के चौथाई हिस्से में सेट करना है, तो android.control.aeRegions को (0, 0, 1000, 750) पर सेट करें. साथ ही, android.control.zoomRatio को 2.0 पर सेट करें. इसके अलावा, ऐप्लिकेशन 1.0 के android.control.zoomRatio के लिए, android.control.aeRegions को (500, 375, 1000, 750) के बराबर क्षेत्र पर सेट कर सकता है.