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

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

कैमरा सबसिस्टम, सभी रिज़ॉल्यूशन और आउटपुट फ़ॉर्मैट के लिए, सिर्फ़ 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) }

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

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

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

उदाहरण के लिए, अगर दो स्ट्रीम तय की जाती हैं, तो 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, 1333, 750) (क्रॉप किए गए हिस्से के बराबर)

crop-region-169-ratio

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

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

crop-region-11-ratio

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

आखिरी उदाहरण के तौर पर, 480 पिक्सल वाली स्ट्रीम के बजाय 1024x1024 स्क्वेयर आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) वाली स्ट्रीम का इस्तेमाल किया गया है:
काटने के लिए चुना गया हिस्सा: (500, 375, 1000, 750) (4:3 आसपेक्ट रेशियो)
1024x1024 स्ट्रीम का काटा गया हिस्सा: (625, 375, 750, 750)
1280x720 स्ट्रीम का काटा गया हिस्सा: (500, 469, 1000, 562)

crop-region-43-square-ratio

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

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

RAW इमेज फ़ाइलों के लिए अतिरिक्त सहायता, 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; ओरिजनल फ़ील्ड ऑफ़ व्यू का 4 गुना (वाइड लेंस से अल्ट्रावाइड लेंस पर स्विच किया गया)
काटा गया हिस्सा: (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 के लिए, (500, 375, 1000, 750) के बराबर android.control.aeRegions सेट कर सकता है.