कैमरे की झलक

ध्यान दें: यह पेज Camera2 पैकेज के बारे में है. हमारा सुझाव है कि जब तक आपके ऐप्लिकेशन को Camera2 की खास और लो-लेवल सुविधाओं की ज़रूरत न हो, तब तक CameraX का इस्तेमाल करें. CameraX और Camera2, दोनों ही Android 5.0 (एपीआई लेवल 21) और इसके बाद के वर्शन पर काम करते हैं.

Android डिवाइसों पर, कैमरे और कैमरे की झलक हमेशा एक ही ओरिएंटेशन में नहीं होती.

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

इस वजह से, कैमरा ऐप्लिकेशन आम तौर पर कैमरे की झलक का आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) और डिवाइस का ओरिएंटेशन. जब फ़ोन का ओरिएंटेशन पोर्ट्रेट होता है, तो कैमरे की झलक, चौड़ाई के मुकाबले लंबाई में ज़्यादा होती है. जब फ़ोन (और कैमरा) को लैंडस्केप मोड में घुमाया जाता है, तो कैमरे की झलक, लंबाई के मुकाबले चौड़ी होती है.

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

कैमरा एडजस्ट करें

कॉन्टेंट बनाने Android पर काम करने के तरीके की परिभाषा यह बताता है कि कैमरा इमेज सेंसर "ओरिएंटेड होना चाहिए, ताकि कैमरे का डाइमेंशन, स्क्रीन के लंबे डाइमेंशन के साथ अलाइन हो जाता है. इसका मतलब है कि जब डिवाइस को लैंडस्केप ओरिएंटेशन में रखा जाता है, तो कैमरों को लैंडस्केप ओरिएंटेशन में फ़ोटो कैप्चर करनी चाहिए. यह डिवाइस के नेचुरल ओरिएंटेशन के बावजूद लागू होता है. इसका मतलब है कि यह लैंडस्केप-प्राइमरी डिवाइसों के साथ-साथ, पोर्ट्रेट-प्राइमरी डिवाइसों पर भी लागू होता है."

कैमरे को स्क्रीन के हिसाब से अरेंज करने से, कैमरा ऐप्लिकेशन में कैमरे के व्यूफ़ाइंडर का डिसप्ले एरिया ज़्यादा से ज़्यादा हो जाता है. साथ ही, इमेज सेंसर आम तौर पर अपना डेटा लैंडस्केप आसपेक्ट रेशियो में दिखाते हैं. इनमें 4:3 सबसे आम है.

पोर्ट्रेट ओरिएंटेशन में, फ़ोन और कैमरा सेंसर.
पहली इमेज. फ़ोन और कैमरा सेंसर के ओरिएंटेशन का सामान्य संबंध.

कैमरा सेंसर का नैचुरल ओरिएंटेशन (स्क्रीन की दिशा) लैंडस्केप होता है. पहली इमेज में, सेंसर सामने वाला कैमरा है (कैमरा जो उसी दिशा में संकेत कर रहा है डिस्प्ले) को फ़ोन से 270 डिग्री घुमाया जाता है, ताकि Android के साथ काम करने की परिभाषा.

ऐप्लिकेशन को सेंसर घुमाने के लिए, camera2 एपीआई में SENSOR_ORIENTATION कॉन्स्टेंट. ज़्यादातर फ़ोन और टैबलेट के लिए, डिवाइस सेंसर ओरिएंटेशन की रिपोर्ट करता है का 270 डिग्री ( सामने का कैमरा) और 90 डिग्री ( डिवाइस के पिछले हिस्से पर) का इस्तेमाल करें. सेंसर भी मौजूद है. आम तौर पर, लैपटॉप कैमरे सेंसर के ओरिएंटेशन की जानकारी 0 या 180 डिग्री के तौर पर देते हैं.

कैमरे के इमेज सेंसर, अपना डेटा (इमेज बफ़र) सेंसर के नेचुरल ओरिएंटेशन (लैंडस्केप) में दिखाते हैं. इसलिए, कैमरे की झलक को डिवाइस के नेचुरल ओरिएंटेशन में दिखाने के लिए, इमेज बफ़र को SENSOR_ORIENTATION में बताए गए डिग्री के हिसाब से घुमाया जाना चाहिए. सामने वाले कैमरों के लिए, इसे घड़ी की उलटी दिशा में घुमाया जाता है; में कर सकते हैं.

उदाहरण के लिए, पहली इमेज में सामने वाले कैमरे के लिए, कैमरा सेंसर से जनरेट किया गया इमेज बफ़र ऐसा दिखता है:

कैमरा सेंसर को इमेज के साथ लैंडस्केप ओरिएंटेशन में घुमाया गया
            तिरछा, ऊपर बाईं ओर.

चित्र को घड़ी की विपरीत दिशा में 270 डिग्री घुमाना चाहिए ताकि पूर्वावलोकन का ओरिएंटेशन, डिवाइस ओरिएंटेशन से मेल खाता है:

पोर्ट्रेट ओरिएंटेशन में कैमरा सेंसर, जिसमें इमेज सीधी है.

पीछे वाला कैमरा, ऊपर दिए गए बफ़र के जैसे ही ओरिएंटेशन वाला इमेज बफ़र जनरेट करेगा, लेकिन SENSOR_ORIENTATION 90 डिग्री का होगा. इस वजह से, बफ़र को घड़ी की सुई की दिशा में 90 डिग्री घुमाया गया.

डिवाइस को घुमाना

डिवाइस को घुमाना वह संख्या है जिससे डिवाइस को अपनी सामान्य सेटिंग के हिसाब से घुमाया जाता है स्क्रीन की दिशा. उदाहरण के लिए, लैंडस्केप ओरिएंटेशन में दिख रहे फ़ोन में डिवाइस है 90 या 270 डिग्री का घूर्णन, जो घूर्णन की दिशा पर निर्भर करता है.

कैमरा सेंसर के इमेज बफ़र को डिवाइस का रोटेशन (सेंसर ओरिएंटेशन की डिग्री के अतिरिक्त) कैमरा झलक को सीधा दिखाने के लिए.

ओरिएंटेशन का हिसाब लगाना

कैमरे की झलक का सही ओरिएंटेशन, सेंसर को ध्यान में रखता है स्क्रीन की दिशा और डिवाइस रोटेशन.

सेंसर इमेज बफ़र के कुल रोटेशन का पता लगाने के लिए, नीचे दिया गया फ़ॉर्मूला:

rotation = (sensorOrientationDegrees - deviceOrientationDegrees * sign + 360) % 360

यहां sign, सामने वाले कैमरे के लिए 1 और पीछे वाले कैमरे के लिए -1 है.

सामने के कैमरों के लिए, चित्र बफ़र को घड़ी की विपरीत दिशा में घुमाया जाता है (से सेंसर का सामान्य ओरिएंटेशन. पीछे के कैमरे के लिए, सेंसर चित्र बफ़र को घड़ी की सुई की दिशा में घुमाया जाता है.

deviceOrientationDegrees * sign + 360 एक्सप्रेशन, डिवाइस के रोटेशन को बदलता है पीछे वाले कैमरों के लिए घड़ी की विपरीत दिशा में से घड़ी की विपरीत दिशा में (उदाहरण के लिए, 270 डिग्री को घड़ी की उलटी दिशा में 90 डिग्री में बदल रहा है). मॉड्यूलो ऑपरेशन, नतीजे को 360 डिग्री से कम पर स्केल करता है. उदाहरण के लिए, रोटेशन के 540 डिग्री को 180 डिग्री पर स्केल करना.

अलग-अलग एपीआई, डिवाइस के रोटेशन की रिपोर्ट अलग-अलग तरीके से करते हैं:

  • Display#getRotation() इसकी मदद से, डिवाइस को घड़ी की उलटी दिशा में घुमाया जाता है (उपयोगकर्ता के पॉइंट से व्यू के साथ). यह वैल्यू जैसा है उसे ऊपर दिए गए फ़ॉर्मूला में लागू किया जाता है.
  • OrientationEventListener#onOrientationChanged() उपयोगकर्ता के नज़रिए से, डिवाइस को घड़ी की दिशा में घुमाने पर दिखने वाला आइडेंटिफ़ायर दिखाता है. ऊपर दिए गए फ़ॉर्मूला में इस्तेमाल करने के लिए, वैल्यू को नेगेटिव करें.

सामने वाले कैमरे

लैंडस्केप ओरिएंटेशन और सेंसर, दोनों में कैमरा प्रीव्यू और सेंसर
            दाईं ओर ऊपर है.
दूसरी इमेज. फ़ोन को 90 डिग्री घुमाकर लैंडस्केप ओरिएंटेशन में, कैमरे की झलक और सेंसर.

यहां दूसरे चित्र में, कैमरा सेंसर से जनरेट किया गया इमेज बफ़र दिखाया गया है:

लैंडस्केप ओरिएंटेशन में कैमरा सेंसर और इमेज अपराइट.

सेंसर को अडजस्ट करने के लिए, बफ़र को घड़ी की उलटी दिशा में 270 डिग्री घुमाना चाहिए स्क्रीन की दिशा (ऊपर कैमरा ओरिएंटेशन देखें):

कैमरा सेंसर को पोर्ट्रेट ओरिएंटेशन में घुमाया गया है. इमेज, साइडवाइज़ और सबसे ऊपर दाईं ओर है.

इसके बाद, डिवाइस के घूमने के हिसाब से बफ़र को 90 डिग्री और घुमाया जाता है, ताकि कैमरे की झलक सही तरीके से दिखे. इसकी वजह से, दूसरे चित्र में कैमरे की झलक सही तरीके से दिखती है:

कैमरा सेंसर को इमेज के साथ लैंडस्केप ओरिएंटेशन में घुमाया गया
            ऊपर की ओर.

यहां कैमरे को दाईं ओर लैंडस्केप ओरिएंटेशन में घुमाया गया है:

कैमरे की झलक और सेंसर, दोनों लैंडस्केप ओरिएंटेशन में हैं, लेकिन
            सेंसर उलटा है.
तीसरी इमेज. फ़ोन को लैंडस्केप ओरिएंटेशन में 270 डिग्री (या -90 डिग्री) घुमाने पर, कैमरे की झलक और सेंसर.

इमेज बफ़र यहां दिया गया है:

कैमरा सेंसर को लैंडस्केप ओरिएंटेशन में घुमाया गया है और इमेज उलटी है.

सेंसर के ओरिएंटेशन में बदलाव करने के लिए, बफ़र को घड़ी की उल्टी दिशा में 270 डिग्री घुमाना होगा:

कैमरा सेंसर को पोर्ट्रेट ओरिएंटेशन के लिए रेटिंग दी गई है. इमेज, बाईं ओर ऊपर की ओर है.

फिर बफ़र को घड़ी की विपरीत दिशा में 270 डिग्री घुमाया जाता है, ताकि डिवाइस को घुमाने के लिए:

कैमरा सेंसर को लैंडस्केप ओरिएंटेशन में घुमाया गया है और इमेज को ऊपर की ओर रखा गया है.

पीछे वाले कैमरे

आम तौर पर, पीछे के कैमरे का सेंसर ओरिएंटेशन 90 डिग्री होता है (जैसा कि जिन्हें डिवाइस के पीछे से देखा गया हो). कैमरे की झलक को ओरिएंट करते समय, सेंसर इमेज बफ़र को घड़ी की सुई की दिशा में घुमाया जाता है. यह घुमाव, सेंसर के घुमाव के हिसाब से होता है, न कि सामने वाले कैमरे की तरह घड़ी की सुई के उलट दिशा में. इसके बाद, डिवाइस के घुमाव के हिसाब से इमेज बफ़र को घड़ी की सुई के उलट दिशा में घुमाया जाता है.

कैमरे की झलक और सेंसर, दोनों लैंडस्केप ओरिएंटेशन में, लेकिन
            सेंसर उलटा है.
चौथी इमेज. लैंडस्केप ओरिएंटेशन में पीछे वाला कैमरा वाला फ़ोन (270 या -90 डिग्री घुमाया गया).

यहां चौथी इमेज में कैमरा सेंसर से इमेज बफ़र की जानकारी दी गई है:

कैमरा सेंसर को लैंडस्केप ओरिएंटेशन में घुमाया गया है और इमेज उलटी है.

सेंसर के ओरिएंटेशन में बदलाव करने के लिए, बफ़र को घड़ी की सुई की दिशा में 90 डिग्री घुमाना होगा:

कैमरा सेंसर को पोर्ट्रेट ओरिएंटेशन के लिए रेटिंग दी गई है. इमेज, बाईं ओर ऊपर की ओर है.

फिर बफ़र को डिवाइस के हिसाब से 270 डिग्री घड़ी की उलटी दिशा में घुमाया जाता है घुमाव:

कैमरा सेंसर को लैंडस्केप ओरिएंटेशन में घुमाया गया है और इमेज को ऊपर की ओर रखा गया है.

आसपेक्ट रेशियो

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

कैमरा सेंसर के इमेज बफ़र का ओरिएंटेशन सही होना चाहिए और उसे इस तरह से स्केल किया जाना चाहिए यूज़र इंटरफ़ेस (यूआई) के तौर पर व्यूफ़ाइंडर यूज़र इंटरफ़ेस (यूआई) एलिमेंट का ओरिएंटेशन और आसपेक्ट रेशियो डिवाइस की स्क्रीन को बदलने के साथ या उसके बिना, स्क्रीन की दिशा को डाइनैमिक तौर पर बदलता है स्क्रीन की दिशा.

डिवाइस के नए नाप या आकार या मल्टी-विंडो या मल्टी-डिसप्ले में, अगर आपके ऐप्लिकेशन को लगता है कि कैमरे की झलक की स्क्रीन की दिशा वही है जो डिवाइस की है ऐसा हो सकता है कि आपकी झलक (पोर्ट्रेट या लैंडस्केप) का फ़ॉर्मैट गलत हो या फिर दोनों का इस्तेमाल करते हैं.

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

पांचवें चित्र में, ऐप्लिकेशन ने गलती से यह मान लिया कि डिवाइस को 90 डिग्री, घड़ी की सुई के उलट घुमाया गया है. इसलिए, ऐप्लिकेशन ने झलक को भी उतनी ही डिग्री घुमाया.

फ़ोल्ड किए जा सकने वाले डिवाइस को अनफ़ोल्ड किया गया है. इसमें कैमरे की झलक ऊपर की ओर है, लेकिन गलत स्केलिंग की वजह से, वह छोटा हो गया है.
छठी इमेज. फ़ोल्ड किए जा सकने वाले डिवाइस, पोर्ट्रेट से लैंडस्केप मोड में बदल जाते हैं आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) में कैमरा सेंसर, पोर्ट्रेट ओरिएंटेशन में बना रहता है.

छठे चित्र में, ऐप्लिकेशन ने इमेज बफ़र के आसपेक्ट रेशियो में बदलाव नहीं किया, ताकि वह कैमरे की झलक दिखाने वाले यूज़र इंटरफ़ेस (यूआई) एलिमेंट के नए डाइमेंशन में सही तरीके से फ़िट हो सके.

फ़िक्स्ड-ओरिएंटेशन कैमरा ऐप्लिकेशन, आम तौर पर फ़ोल्ड किए जा सकने वाले डिवाइसों और लैपटॉप जैसी बड़ी स्क्रीन वाले अन्य डिवाइसों पर काम नहीं करते:

लैपटॉप पर कैमरे की झलक सीधे तौर पर दिख रही है, लेकिन ऐप्लिकेशन का यूज़र इंटरफ़ेस (यूआई), तिरछा है.
सातवीं इमेज. लैपटॉप कंप्यूटर पर फ़िक्स्ड-ओरिएंटेशन पोर्ट्रेट ऐप्लिकेशन.

सातवें चित्र में, कैमरा ऐप्लिकेशन का यूज़र इंटरफ़ेस (यूआई) साइडवाइज़ है, क्योंकि ऐप्लिकेशन का ओरिएंटेशन सिर्फ़ पोर्ट्रेट पर सेट है. व्यूफ़ाइंडर इमेज, कैमरा सेंसर के हिसाब से सही तरीके से ओरिएंट की गई हो.

इनसेट पोर्ट्रेट मोड

जिन कैमरा ऐप्लिकेशन में मल्टी-विंडो मोड (resizeableActivity="false") काम नहीं करता और जिनमें ओरिएंटेशन (screenOrientation="portrait" या screenOrientation="landscape") पर पाबंदी होती है उन्हें बड़ी स्क्रीन वाले डिवाइसों पर इनसेट पोर्ट्रेट मोड में रखा जा सकता है, ताकि कैमरे की झलक को सही तरीके से दिखाया जा सके.

सिर्फ़ पोर्ट्रेट मोड में काम करने वाले ऐप्लिकेशन को पोर्ट्रेट ओरिएंटेशन में इनसेट करें. भले ही, डिसप्ले का आसपेक्ट रेशियो लैंडस्केप हो. सिर्फ़ लैंडस्केप मोड में काम करने वाले ऐप्लिकेशन, लैंडस्केप ओरिएंटेशन में लेटरबॉक्स किए जाते हैं. भले ही, डिसप्ले का आसपेक्ट रेशियो पोर्ट्रेट हो. ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) के साथ अलाइन करने के लिए, कैमरे की इमेज को घुमाया जाता है. साथ ही, कैमरे की झलक के आसपेक्ट रेशियो से मैच करने के लिए उसे काटा जाता है. इसके बाद, झलक को भरने के लिए उसे स्केल किया जाता है.

इनसेट पोर्ट्रेट मोड तब ट्रिगर होता है, जब कैमरे के इमेज सेंसर का आसपेक्ट रेशियो और ऐप्लिकेशन की मुख्य गतिविधि का आसपेक्ट रेशियो मेल नहीं खाता.

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

आठवें चित्र में, सिर्फ़ पोर्ट्रेट मोड में काम करने वाले कैमरे के ऐप्लिकेशन को घुमाया गया है, ताकि लैपटॉप के डिसप्ले पर यूज़र इंटरफ़ेस (यूआई) को सीधा दिखाया जा सके. पोर्ट्रेट ऐप्लिकेशन और लैंडस्केप डिसप्ले के आसपेक्ट रेशियो में अंतर की वजह से, ऐप्लिकेशन को लेटरबॉक्स किया गया है. कैमरे की झलक वाली इमेज को घुमाया गया है, ताकि ऐप्लिकेशन के यूज़र इंटरफ़ेस (इनसेट पोर्ट्रेट मोड की वजह से) के घूमने की भरपाई की जा सके. साथ ही, इमेज को पोर्ट्रेट ओरिएंटेशन में फ़िट करने के लिए काटा और स्केल किया गया है, जिससे फ़ील्ड ऑफ़ व्यू कम हो गया है.

घुमाएं, काटें, स्केल करें

डिसप्ले पर सिर्फ़ पोर्ट्रेट मोड में सेट किए गए कैमरा ऐप्लिकेशन के लिए, इनसेट पोर्ट्रेट मोड शुरू किया गया जिनका आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) लैंडस्केप मोड में है:

लैपटॉप पर कैमरे की झलक सीधे तौर पर दिख रही है, लेकिन ऐप्लिकेशन का यूज़र इंटरफ़ेस (यूआई), तिरछा है.
नौवीं इमेज. लैपटॉप पर पोर्ट्रेट ओरिएंटेशन में फ़िक्स किया गया ऐप्लिकेशन.

ऐप्लिकेशन, पोर्ट्रेट ओरिएंटेशन में लेटरबॉक्स किया गया हो:

ऐप्लिकेशन को पोर्ट्रेट ओरिएंटेशन में घुमाया गया और लेटरबॉक्स किया गया. इमेज है
            तिरछा, ऊपर दाईं ओर.

कैमरे की इमेज को 90 डिग्री घुमाया गया, ताकि फ़ोटो की दिशा बदल सके ऐप्लिकेशन:

सेंसर इमेज को 90 डिग्री घुमाकर, उसे सीधा किया गया.

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

कैमरे की झलक दिखाने के लिए, काटी गई इमेज का साइज़ बदला गया.

फ़ोल्ड किए जा सकने वाले डिवाइसों पर, कैमरा सेंसर का ओरिएंटेशन पोर्ट्रेट हो सकता है, जबकि डिसप्ले का आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) लैंडस्केप हो सकता है:

कैमरे की झलक और ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) को, अनफ़ोल्ड किए गए वाइड डिसप्ले पर, साइड में घुमाया गया है.
10वां डायग्राम. सिर्फ़ पोर्ट्रेट मोड में काम करने वाले कैमरा ऐप्लिकेशन के साथ, अनफ़ोल्ड किए गए डिवाइस की इमेज. साथ ही, कैमरा सेंसर और डिसप्ले के अलग-अलग आसपेक्ट रेशियो की इमेज.

सेंसर की स्क्रीन की दिशा को अडजस्ट करने के लिए, कैमरे की झलक को घुमाया गया. व्यूफ़ाइंडर में इमेज सही दिशा में है, लेकिन सिर्फ़ पोर्ट्रेट मोड में काम करने वाला ऐप्लिकेशन है तिरछा है.

इनसेट पोर्ट्रेट मोड में ऐप्लिकेशन को सिर्फ़ पोर्ट्रेट ओरिएंटेशन में लेटरबॉक्स करना होगा ऐप्लिकेशन और कैमरे की झलक को ठीक से ओरिएंटेशन में लाने के लिए:

फ़ोल्ड किए जा सकने वाले डिवाइस पर, पोर्ट्रेट ओरिएंटेशन में लेटरबॉक्स किया गया ऐप्लिकेशन. इसमें कैमरे की झलक, स्क्रीन पर ऊपर की ओर दिख रही है.

एपीआई

Android 12 (एपीआई लेवल 31) के बाद, ऐप्लिकेशन CaptureRequest क्लास की SCALER_ROTATE_AND_CROP प्रॉपर्टी का इस्तेमाल करके, इनसेट पोर्ट्रेट मोड को साफ़ तौर पर कंट्रोल कर सकते हैं.

डिफ़ॉल्ट वैल्यू SCALER_ROTATE_AND_CROP_AUTO है. इससे सिस्टम, इनसेट पोर्ट्रेट मोड को चालू कर सकता है. SCALER_ROTATE_AND_CROP_90 इनसेट पोर्ट्रेट मोड की तरह ही काम करता है.

सभी डिवाइसों पर, SCALER_ROTATE_AND_CROP की सभी वैल्यू काम नहीं करतीं. इस्तेमाल की जा सकने वाली वैल्यू की सूची पाने के लिए, CameraCharacteristics#SCALER_AVAILABLE_ROTATE_AND_CROP_MODES देखें.

CameraX

Jetpack CameraX लाइब्रेरी की मदद से, कैमरे का व्यूफ़ाइंडर आसानी से बनाया जा सकता है. यह सेंसर ओरिएंटेशन और डिवाइस के घूमने के हिसाब से काम करता है.

PreviewView लेआउट एलिमेंट इससे कैमरे की झलक दिखती है, जो सेंसर ओरिएंटेशन के लिए अपने-आप अडजस्ट हो जाती है. और स्केलिंग. PreviewView, कैमरे की इमेज का आसपेक्ट रेशियो बनाए रखता है. इसके लिए, वह FILL_CENTER स्केल टाइप लागू करता है. यह स्केल टाइप, इमेज को बीच में रखता है, लेकिन PreviewView के डाइमेंशन से मैच करने के लिए, उसे काट सकता है. कैमरा इमेज को लेटरबॉक्स करने के लिए, स्केल टाइप को FIT_CENTER.

PreviewView की मदद से कैमरा प्रीव्यू बनाने की बुनियादी बातें जानने के लिए, देखें झलक लागू करना.

सैंपल लागू करने के बारे में जानने के लिए, इसे देखें CameraXBasic GitHub पर डेटा स्टोर करने की जगह.

CameraViewfinder

झलक इस्तेमाल के उदाहरण की तरह ही, कैमराव्यूफ़ाइंडर लाइब्रेरी में ऐसे टूल का सेट मौजूद है जिनकी मदद से कैमरा प्रीव्यू बनाना आसान हो जाता है. यह CameraX Core पर निर्भर नहीं करता. इसलिए, इसे अपने मौजूदा Camera2 कोडबेस में आसानी से इंटिग्रेट किया जा सकता है.

Camera2 के कैमरे फ़ीड को दिखाने के लिए, Surface का इस्तेमाल करने के बजाय, CameraViewfinder विजेट का इस्तेमाल किया जा सकता है.

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

CameraViewfinder ऑब्जेक्ट से सरफ़ेस का अनुरोध करने के लिए, आपको ये काम करने होंगे ViewfinderSurfaceRequest बनाएं.

इस अनुरोध में, CameraCharacteristics से मिले डिवाइस के कैमरे और स्क्रीन रिज़ॉल्यूशन की ज़रूरी शर्तें शामिल हैं.

requestSurfaceAsync() को कॉल किया जा रहा है प्लैटफ़ॉर्म उपलब्ध कराने वाले को अनुरोध भेजता है, जो कि TextureView या SurfaceView और Surface का ListenableFuture पाएं.

markSurfaceSafeToRelease() को कॉल किया जा रहा है प्लैटफ़ॉर्म उपलब्ध कराने वाली कंपनी को यह सूचना देता है कि इस प्लैटफ़ॉर्म की ज़रूरत नहीं है और यह जानकारी एक-दूसरे से जुड़ी हुई है संसाधन रिलीज़ किए जा सकते हैं.

KotlinJava
fun startCamera(){
    val previewResolution = Size(width, height)
    val viewfinderSurfaceRequest =
        ViewfinderSurfaceRequest(previewResolution, characteristics)
    val surfaceListenableFuture =
        cameraViewfinder.requestSurfaceAsync(viewfinderSurfaceRequest)

    Futures.addCallback(surfaceListenableFuture, object : FutureCallback<Surface> {
        override fun onSuccess(surface: Surface) {
            /* create a CaptureSession using this surface as usual */
        }
        override fun onFailure(t: Throwable) { /* something went wrong */}
    }, ContextCompat.getMainExecutor(context))
}
    void startCamera(){
        Size previewResolution = new Size(width, height);
        ViewfinderSurfaceRequest viewfinderSurfaceRequest =
                new ViewfinderSurfaceRequest(previewResolution, characteristics);
        ListenableFuture<Surface> surfaceListenableFuture =
                cameraViewfinder.requestSurfaceAsync(viewfinderSurfaceRequest);

        Futures.addCallback(surfaceListenableFuture, new FutureCallback<Surface>() {
            @Override
            public void onSuccess(Surface result) {
                /* create a CaptureSession using this surface as usual */
            }
            @Override public void onFailure(Throwable t) { /* something went wrong */}
        },  ContextCompat.getMainExecutor(context));
    }

SurfaceView

SurfaceView इसका इस्तेमाल करके, आसानी से कैमरा प्रीव्यू बनाया जा सकता है. इसके लिए प्रोसेसिंग की ज़रूरत होती है और इसे ऐनिमेट नहीं किया जाता.

SurfaceView, डिसप्ले ओरिएंटेशन से मैच करने के लिए, कैमरा सेंसर इमेज बफ़र को अपने-आप घुमाता है. इसमें सेंसर ओरिएंटेशन और डिवाइस के रोटेशन, दोनों को ध्यान में रखा जाता है. हालांकि, इमेज बफ़र को SurfaceView के डाइमेंशन में फ़िट करने के लिए स्केल किया जाता है. इसमें आसपेक्ट रेशियो का कोई ध्यान नहीं रखा जाता.

आपको यह पक्का करना होगा कि इमेज बफ़र का आसपेक्ट रेशियो, SurfaceView के आसपेक्ट रेशियो से मेल खाता हो. ऐसा करने के लिए, कॉम्पोनेंट के onMeasure() तरीके में SurfaceView के कॉन्टेंट को स्केल करें:

(computeRelativeRotation() का सोर्स कोड इसमें है नीचे सापेक्ष रोटेशन.)

KotlinJava
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    val width = MeasureSpec.getSize(widthMeasureSpec)
    val height = MeasureSpec.getSize(heightMeasureSpec)

    val relativeRotation = computeRelativeRotation(characteristics, surfaceRotationDegrees)

    if (previewWidth > 0f && previewHeight > 0f) {
        /* Scale factor required to scale the preview to its original size on the x-axis. */
        val scaleX =
            if (relativeRotation % 180 == 0) {
                width.toFloat() / previewWidth
            } else {
                width.toFloat() / previewHeight
            }
        /* Scale factor required to scale the preview to its original size on the y-axis. */
        val scaleY =
            if (relativeRotation % 180 == 0) {
                height.toFloat() / previewHeight
            } else {
                height.toFloat() / previewWidth
            }

        /* Scale factor required to fit the preview to the SurfaceView size. */
        val finalScale = min(scaleX, scaleY)

        setScaleX(1 / scaleX * finalScale)
        setScaleY(1 / scaleY * finalScale)
    }
    setMeasuredDimension(width, height)
}
@Override
void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);

    int relativeRotation = computeRelativeRotation(characteristics, surfaceRotationDegrees);

    if (previewWidth > 0f && previewHeight > 0f) {

        /* Scale factor required to scale the preview to its original size on the x-axis. */
        float scaleX = (relativeRotation % 180 == 0)
                       ? (float) width / previewWidth
                       : (float) width / previewHeight;

        /* Scale factor required to scale the preview to its original size on the y-axis. */
        float scaleY = (relativeRotation % 180 == 0)
                       ? (float) height / previewHeight
                       : (float) height / previewWidth;

        /* Scale factor required to fit the preview to the SurfaceView size. */
        float finalScale = Math.min(scaleX, scaleY);

        setScaleX(1 / scaleX * finalScale);
        setScaleY(1 / scaleY * finalScale);
    }
    setMeasuredDimension(width, height);
}

SurfaceView को कैमरे की झलक के तौर पर लागू करने के बारे में ज़्यादा जानकारी के लिए, यह देखें कैमरे की स्क्रीन की दिशा.

टेक्स्चर व्यू

TextureView, SurfaceView की तुलना में कम परफ़ॉर्म करता है और इसमें ज़्यादा काम करना पड़ता है. हालांकि, TextureView की मदद से कैमरे की झलक को ज़्यादा से ज़्यादा कंट्रोल किया जा सकता है.

TextureView, सेंसर ओरिएंटेशन के आधार पर सेंसर इमेज बफ़र को घुमाता है. हालांकि, यह डिवाइस के रोटेशन या झलक को स्केल करने की सुविधा को मैनेज नहीं करता.

स्केलिंग और रोटेशन को मैट्रिक्स ट्रांसफ़ॉर्मेशन में एन्कोड किया जा सकता है. यह जानने के लिए कि TextureView को सही तरीके से स्केल और घुमाएं. कैमरा ऐप्लिकेशन में साइज़ बदले जा सकने वाले प्लैटफ़ॉर्म इस्तेमाल किए जा सकते हैं

रिलेटिव रोटेशन

कैमरा सेंसर का रिलेटिव रोटेशन वह मात्रा है जो कैमरा सेंसर के आउटपुट को डिवाइस की स्क्रीन की दिशा के साथ अलाइन करें.

रिलेटिव रोटेशन का इस्तेमाल, SurfaceView और TextureView जैसे कॉम्पोनेंट करते हैं. इससे, झलक दिखाने वाली इमेज के लिए x और y स्केलिंग फ़ैक्टर तय किए जाते हैं. इसका इस्तेमाल इन कामों के लिए भी किया जाता है सेंसर इमेज बफ़र के रोटेशन की जानकारी दें.

कॉन्टेंट बनाने CameraCharacteristics और Surface क्लास कैमरा सेंसर का रिलेटिव रोटेशन:

KotlinJava
/**
 * Computes rotation required to transform the camera sensor output orientation to the
 * device's current orientation in degrees.
 *
 * @param characteristics The CameraCharacteristics to query for the sensor orientation.
 * @param surfaceRotationDegrees The current device orientation as a Surface constant.
 * @return Relative rotation of the camera sensor output.
 */
public fun computeRelativeRotation(
    characteristics: CameraCharacteristics,
    surfaceRotationDegrees: Int
): Int {
    val sensorOrientationDegrees =
        characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION)!!

    // Reverse device orientation for back-facing cameras.
    val sign = if (characteristics.get(CameraCharacteristics.LENS_FACING) ==
        CameraCharacteristics.LENS_FACING_FRONT
    ) 1 else -1

    // Calculate desired orientation relative to camera orientation to make
    // the image upright relative to the device orientation.
    return (sensorOrientationDegrees - surfaceRotationDegrees * sign + 360) % 360
}
/**
 * Computes rotation required to transform the camera sensor output orientation to the
 * device's current orientation in degrees.
 *
 * @param characteristics The CameraCharacteristics to query for the sensor orientation.
 * @param surfaceRotationDegrees The current device orientation as a Surface constant.
 * @return Relative rotation of the camera sensor output.
 */
public int computeRelativeRotation(
    CameraCharacteristics characteristics,
    int surfaceRotationDegrees
){
    Integer sensorOrientationDegrees =
        characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);

    // Reverse device orientation for back-facing cameras.
    int sign = characteristics.get(CameraCharacteristics.LENS_FACING) ==
        CameraCharacteristics.LENS_FACING_FRONT ? 1 : -1;

    // Calculate desired orientation relative to camera orientation to make
    // the image upright relative to the device orientation.
    return (sensorOrientationDegrees - surfaceRotationDegrees * sign + 360) % 360;
}

विंडो की मेट्रिक

कैमरे के व्यूफ़ाइंडर के डाइमेंशन तय करने के लिए, स्क्रीन के साइज़ का इस्तेमाल नहीं किया जाना चाहिए. ऐसा इसलिए, क्योंकि हो सकता है कि कैमरा ऐप्लिकेशन, स्क्रीन के किसी हिस्से में चल रहा हो. जैसे, मोबाइल डिवाइसों पर मल्टी-विंडो मोड में या ChromeOS पर फ़्री-फ़ॉर्म मोड में.

WindowManager#getCurrentWindowMetrics() (एपीआई लेवल 30 में जोड़ा गया) स्क्रीन के साइज़ के बजाय, ऐप्लिकेशन विंडो का साइज़ दिखाता है. Jetpack WindowManager लाइब्रेरी के तरीके WindowMetricsCalculator#computeCurrentWindowMetrics() और WindowInfoTracker#currentWindowMetrics() एपीआई लेवल 14 के पुराने सिस्टम के साथ काम करने की सुविधा के साथ भी मिलती है.

180 डिग्री का घुमाव

डिवाइस को 180 डिग्री घुमाने पर (उदाहरण के लिए, सामान्य ओरिएंटेशन से उलटे ओरिएंटेशन में), onConfigurationChanged() कॉलबैक ट्रिगर नहीं होता. इस वजह से, कैमरे की झलक उल्टी दिख सकती है.

180 डिग्री के रोटेशन का पता लगाने के लिए, DisplayListener को लागू करें और onDisplayChanged() कॉलबैक में Display#getRotation() को कॉल करके, डिवाइस के रोटेशन की जांच करें.

खास संसाधन

Android 10 से पहले, मल्टी-विंडो वाले एनवायरमेंट में सबसे ऊपर दिखने वाली ऐक्टिविटी ही RESUMED स्टेटस में होती थी. यह लोगों के लिए उलझन भरा था, क्योंकि सिस्टम ने इस बात का कोई संकेत नहीं दिया कि कौनसी गतिविधि फिर से शुरू हो गई है.

Android 10 (एपीआई लेवल 29) में, एक से ज़्यादा ऐप्लिकेशन फिर से शुरू करने की सुविधा जोड़ी गई है. इसमें, दिखने वाली सभी ऐक्टिविटी RESUMED स्थिति में होती हैं. दिखने वाली गतिविधियां, PAUSED स्थिति में तब भी जा सकती हैं, जब गतिविधि के ऊपर कोई पारदर्शी गतिविधि हो या गतिविधि पर फ़ोकस न किया जा सके. जैसे, पिक्चर में पिक्चर मोड में (पिक्चर में पिक्चर मोड के साथ काम करने की सुविधा देखें).

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

ज़्यादा जानकारी के लिए, यह देखें एक से ज़्यादा बार फिर से शुरू करें.

अन्य संसाधन