Camera API

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

ध्यान दें: इस पेज पर, Camera क्लास के बारे में बताया गया है. अब इसका इस्तेमाल नहीं किया जाता. हमारा सुझाव है कि आप CameraX Jetpack लाइब्रेरी का इस्तेमाल करें. इसके अलावा, इस्तेमाल के कुछ खास मामलों के लिए, camera2 क्लास का इस्तेमाल करें. CameraX और Camera2, दोनों Android 5.0 (एपीआई लेवल 21) और इसके बाद के वर्शन पर काम करते हैं.

ज़रूरी बातें

Android डिवाइसों पर कैमरे इस्तेमाल करने के लिए, अपने ऐप्लिकेशन को अनुमति देने से पहले आपको कुछ सवालों के जवाब देने होंगे. ये सवाल इस बारे में होंगे कि आपका ऐप्लिकेशन, इस हार्डवेयर सुविधा का इस्तेमाल कैसे करेगा.

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

बुनियादी बातें

Android फ़्रेमवर्क, android.hardware.camera2 एपीआई या कैमरा Intent की मदद से इमेज और वीडियो कैप्चर करने की सुविधा देता है. यहां काम की क्लास दी गई हैं:

android.hardware.camera2
यह पैकेज, डिवाइस के कैमरों को कंट्रोल करने के लिए मुख्य एपीआई है. कैमरा ऐप्लिकेशन बनाते समय, इसका इस्तेमाल फ़ोटो या वीडियो लेने के लिए किया जा सकता है.
Camera
यह क्लास, डिवाइस के कैमरों को कंट्रोल करने के लिए इस्तेमाल किया जाने वाला पुराना एपीआई है. अब इसका इस्तेमाल नहीं किया जाता.
SurfaceView
इस क्लास का इस्तेमाल, उपयोगकर्ता को लाइव कैमरा की झलक दिखाने के लिए किया जाता है.
MediaRecorder
इस क्लास का इस्तेमाल, कैमरे से वीडियो रिकॉर्ड करने के लिए किया जाता है.
Intent
Camera ऑब्जेक्ट का सीधे तौर पर इस्तेमाल किए बिना, इमेज या वीडियो कैप्चर करने के लिए, MediaStore.ACTION_IMAGE_CAPTURE या MediaStore.ACTION_VIDEO_CAPTURE के
इंटेंट ऐक्शन टाइप का इस्तेमाल किया जा सकता है.

मेनिफ़ेस्ट में किए गए एलान

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

  • कैमरा ऐक्सेस करने की अनुमति - आपके ऐप्लिकेशन को डिवाइस का कैमरा इस्तेमाल करने की अनुमति मांगनी होगी.
    <uses-permission android:name="android.permission.CAMERA" />

    ध्यान दें: अगर किसी मौजूदा कैमरा ऐप्लिकेशन को शुरू करके कैमरे का इस्तेमाल किया जा रहा है, तो आपके ऐप्लिकेशन को इस अनुमति का अनुरोध करने की ज़रूरत नहीं है.

  • कैमरे की सुविधाएं - आपके ऐप्लिकेशन को कैमरे की सुविधाओं के इस्तेमाल के बारे में भी बताना होगा. उदाहरण के लिए:
    <uses-feature android:name="android.hardware.camera" />

    कैमरे की सुविधाओं की सूची के लिए, मेनिफ़ेस्ट सुविधाओं का रेफ़रंस देखें.

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

    अगर आपका ऐप्लिकेशन ठीक से काम करने के लिए, कैमरे या कैमरे की सुविधा का इस्तेमाल कर सकता है, लेकिन उसे इसकी ज़रूरत नहीं है, तो आपको मेनिफ़ेस्ट में android:required एट्रिब्यूट को शामिल करके और उसे false पर सेट करके यह जानकारी देनी चाहिए:

    <uses-feature android:name="android.hardware.camera" android:required="false" />
  • स्टोरेज की अनुमति - आपका ऐप्लिकेशन, डिवाइस के बाहरी स्टोरेज (एसडी कार्ड) में इमेज या वीडियो सेव कर सकता है. ऐसा तब होता है, जब वह Android 10 (एपीआई लेवल 29) या इससे पहले के वर्शन को टारगेट करता हो और मेनिफ़ेस्ट में यह जानकारी देता हो.
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  • ऑडियो रिकॉर्ड करने की अनुमति - वीडियो कैप्चर करने के साथ-साथ ऑडियो रिकॉर्ड करने के लिए, आपके ऐप्लिकेशन को ऑडियो कैप्चर करने की अनुमति का अनुरोध करना होगा.
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
  • जगह की जानकारी की अनुमति - अगर आपका ऐप्लिकेशन, जीपीएस से मिली जगह की जानकारी के साथ इमेज को टैग करता है, तो आपको ACCESS_FINE_LOCATION अनुमति का अनुरोध करना होगा. ध्यान दें कि अगर आपका ऐप्लिकेशन Android 5.0 (एपीआई लेवल 21) या इसके बाद के वर्शन को टारगेट करता है, तो आपको यह भी एलान करना होगा कि आपका ऐप्लिकेशन डिवाइस के जीपीएस का इस्तेमाल करता है:

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    ...
    <!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
    <uses-feature android:name="android.hardware.location.gps" />

    उपयोगकर्ता की जगह की जानकारी पाने के बारे में ज़्यादा जानने के लिए, जगह की जानकारी पाने की रणनीतियां देखें.

मौजूदा कैमरा ऐप्लिकेशन इस्तेमाल करना

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

कैमरा ऐप्लिकेशन बनाना

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

ध्यान दें: यह गाइड, Camera एपीआई के पुराने वर्शन के लिए है, जो अब काम नहीं करता. नए या बेहतर कैमरा ऐप्लिकेशन के लिए, नए android.hardware.camera2 एपीआई का इस्तेमाल करने का सुझाव दिया जाता है.

अपने ऐप्लिकेशन के लिए कस्टम कैमरा इंटरफ़ेस बनाने का सामान्य तरीका यहां बताया गया है:

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

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

चेतावनी: जब आपका ऐप्लिकेशन Camera ऑब्जेक्ट का इस्तेमाल कर ले, तो Camera.release() को कॉल करके उसे रिलीज़ करना न भूलें! अगर आपका ऐप्लिकेशन कैमरे को सही तरीके से रिलीज़ नहीं करता है, तो कैमरे को ऐक्सेस करने की बाद की सभी कोशिशें नाकाम हो जाएंगी. इनमें आपके ऐप्लिकेशन की कोशिशें भी शामिल हैं. इससे आपका ऐप्लिकेशन या अन्य ऐप्लिकेशन बंद हो सकते हैं.

कैमरे के हार्डवेयर का पता लगाया जा रहा है

अगर आपके ऐप्लिकेशन को मेनिफ़ेस्ट एलान का इस्तेमाल करके, कैमरे की खास तौर पर ज़रूरत नहीं है, तो आपको यह देखना चाहिए कि रनटाइम के दौरान कैमरा उपलब्ध है या नहीं. यह जांच करने के लिए, PackageManager.hasSystemFeature() तरीके का इस्तेमाल करें. इसके बारे में नीचे दिए गए उदाहरण कोड में बताया गया है:

Kotlin

/** Check if this device has a camera */
private fun checkCameraHardware(context: Context): Boolean {
    if (context.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
        // this device has a camera
        return true
    } else {
        // no camera on this device
        return false
    }
}

Java

/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
        // this device has a camera
        return true;
    } else {
        // no camera on this device
        return false;
    }
}

Android डिवाइसों में कई कैमरे हो सकते हैं. उदाहरण के लिए, फ़ोटोग्राफ़ी के लिए पीछे वाला कैमरा और वीडियो कॉल के लिए सामने वाला कैमरा. Android 2.3 (एपीआई लेवल 9) और इसके बाद के वर्शन में, Camera.getNumberOfCameras() तरीके का इस्तेमाल करके, डिवाइस पर उपलब्ध कैमरों की संख्या देखी जा सकती है.

कैमरों को ऐक्सेस करना

अगर आपको पता है कि जिस डिवाइस पर आपका ऐप्लिकेशन चल रहा है उसमें कैमरा है, तो आपको Camera का इंस्टेंस लेकर उसे ऐक्सेस करने का अनुरोध करना होगा. हालांकि, अगर कैमरे को ऐक्सेस करने के लिए इंटेंट का इस्तेमाल किया जा रहा है, तो ऐसा करने की ज़रूरत नहीं है.

प्राइमरी कैमरे को ऐक्सेस करने के लिए, Camera.open() तरीके का इस्तेमाल करें. साथ ही, किसी भी अपवाद को पकड़ना न भूलें, जैसा कि यहां दिए गए कोड में दिखाया गया है:

Kotlin

/** A safe way to get an instance of the Camera object. */
fun getCameraInstance(): Camera? {
    return try {
        Camera.open() // attempt to get a Camera instance
    } catch (e: Exception) {
        // Camera is not available (in use or does not exist)
        null // returns null if camera is unavailable
    }
}

Java

/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
    }
    catch (Exception e){
        // Camera is not available (in use or does not exist)
    }
    return c; // returns null if camera is unavailable
}

चेतावनी: Camera.open() का इस्तेमाल करते समय, हमेशा अपवादों की जांच करें. अगर कैमरा इस्तेमाल में है या मौजूद नहीं है, तो अपवादों की जांच न करने पर, सिस्टम आपके ऐप्लिकेशन को बंद कर देगा.

Android 2.3 (एपीआई लेवल 9) या इसके बाद के वर्शन वाले डिवाइसों पर, Camera.open(int) का इस्तेमाल करके कुछ खास कैमरे ऐक्सेस किए जा सकते हैं. ऊपर दिया गया उदाहरण कोड, एक से ज़्यादा कैमरे वाले डिवाइस पर पहले, पीछे की ओर मौजूद कैमरे को ऐक्सेस करेगा.

कैमरे की सुविधाओं की जांच की जा रही है

कैमरे का ऐक्सेस मिलने के बाद, उसकी सुविधाओं के बारे में ज़्यादा जानकारी पाई जा सकती है. इसके लिए, Camera.getParameters() तरीके का इस्तेमाल करें और वापस किए गए Camera.Parameters ऑब्जेक्ट की जांच करें. एपीआई लेवल 9 या इसके बाद के वर्शन का इस्तेमाल करते समय, Camera.getCameraInfo() का इस्तेमाल करके यह पता लगाएं कि कैमरा डिवाइस के सामने है या पीछे. साथ ही, इमेज का ओरिएंटेशन भी पता लगाएं.

झलक दिखाने वाली क्लास बनाना

उपयोगकर्ताओं को अच्छी फ़ोटो या वीडियो लेने के लिए, यह देखना ज़रूरी है कि डिवाइस के कैमरे में क्या दिख रहा है. कैमरा की झलक दिखाने वाली क्लास एक SurfaceView है, जो कैमरे से मिलने वाले लाइव इमेज डेटा को दिखा सकती है. इससे उपयोगकर्ता, फ़ोटो या वीडियो को फ़्रेम और कैप्चर कर सकते हैं.

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

Kotlin

/** A basic Camera preview class */
class CameraPreview(
        context: Context,
        private val mCamera: Camera
) : SurfaceView(context), SurfaceHolder.Callback {

    private val mHolder: SurfaceHolder = holder.apply {
        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        addCallback(this@CameraPreview)
        // deprecated setting, but required on Android versions prior to 3.0
        setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS)
    }

    override fun surfaceCreated(holder: SurfaceHolder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        mCamera.apply {
            try {
                setPreviewDisplay(holder)
                startPreview()
            } catch (e: IOException) {
                Log.d(TAG, "Error setting camera preview: ${e.message}")
            }
        }
    }

    override fun surfaceDestroyed(holder: SurfaceHolder) {
        // empty. Take care of releasing the Camera preview in your activity.
    }

    override fun surfaceChanged(holder: SurfaceHolder, format: Int, w: Int, h: Int) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.
        if (mHolder.surface == null) {
            // preview surface does not exist
            return
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview()
        } catch (e: Exception) {
            // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        mCamera.apply {
            try {
                setPreviewDisplay(mHolder)
                startPreview()
            } catch (e: Exception) {
                Log.d(TAG, "Error starting camera preview: ${e.message}")
            }
        }
    }
}

Java

/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null){
          // preview surface does not exist
          return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
          // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }
}

अगर आपको कैमरे की झलक के लिए कोई खास साइज़ सेट करना है, तो इसे surfaceChanged() तरीके से सेट करें. इसके बारे में ऊपर दी गई टिप्पणियों में बताया गया है. झलक का साइज़ सेट करते समय, आपको getSupportedPreviewSizes() से मिली वैल्यू का इस्तेमाल करना होगा. setPreviewSize() तरीके में, अपनी मर्ज़ी से वैल्यू सेट न करें.

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

लेआउट में झलक दिखाना

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

यहां दिया गया लेआउट कोड, एक बहुत ही बुनियादी व्यू उपलब्ध कराता है. इसका इस्तेमाल, कैमरे की झलक दिखाने के लिए किया जा सकता है. इस उदाहरण में, FrameLayout एलिमेंट को कैमरे की झलक वाली क्लास के लिए कंटेनर के तौर पर इस्तेमाल किया गया है. इस लेआउट टाइप का इस्तेमाल इसलिए किया जाता है, ताकि लाइव कैमरा की झलक वाली इमेज पर, इमेज की अतिरिक्त जानकारी या कंट्रोल ओवरले किए जा सकें.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <FrameLayout
    android:id="@+id/camera_preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    />

  <Button
    android:id="@+id/button_capture"
    android:text="Capture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    />
</LinearLayout>

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

<activity android:name=".CameraActivity"
          android:label="@string/app_name"

          android:screenOrientation="landscape">
          <!-- configure this activity to use landscape orientation -->

          <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

ध्यान दें: कैमरे की झलक को लैंडस्केप मोड में होना ज़रूरी नहीं है. Android 2.2 (एपीआई लेवल 8) से, setDisplayOrientation() तरीके का इस्तेमाल करके, झलक वाली इमेज को घुमाने की सुविधा सेट की जा सकती है. जब उपयोगकर्ता फ़ोन का ओरिएंटेशन बदलता है, तो झलक का ओरिएंटेशन बदलने के लिए, अपनी झलक क्लास के surfaceChanged() तरीके में, पहले Camera.stopPreview() से झलक को रोकें. इसके बाद, ओरिएंटेशन बदलें और फिर Camera.startPreview() से झलक को फिर से शुरू करें.

कैमरा व्यू की गतिविधि में, ऊपर दिए गए उदाहरण में दिखाए गए FrameLayout एलिमेंट में अपनी झलक वाली क्लास जोड़ें. कैमरे की गतिविधि को यह भी पक्का करना चाहिए कि रोके जाने या बंद होने पर, वह कैमरे को रिलीज़ कर दे. यहां दिए गए उदाहरण में, कैमरे की गतिविधि में बदलाव करने का तरीका बताया गया है. इससे, झलक दिखाने वाली क्लास बनाना में दिखाई गई झलक दिखाने वाली क्लास को अटैच किया जा सकता है.

Kotlin

class CameraActivity : Activity() {

    private var mCamera: Camera? = null
    private var mPreview: CameraPreview? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Create an instance of Camera
        mCamera = getCameraInstance()

        mPreview = mCamera?.let {
            // Create our Preview view
            CameraPreview(this, it)
        }

        // Set the Preview view as the content of our activity.
        mPreview?.also {
            val preview: FrameLayout = findViewById(R.id.camera_preview)
            preview.addView(it)
        }
    }
}

Java

public class CameraActivity extends Activity {

    private Camera mCamera;
    private CameraPreview mPreview;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Create an instance of Camera
        mCamera = getCameraInstance();

        // Create our Preview view and set it as the content of our activity.
        mPreview = new CameraPreview(this, mCamera);
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview.addView(mPreview);
    }
}

ध्यान दें: ऊपर दिए गए उदाहरण में getCameraInstance() तरीका, कैमरे ऐक्सेस करना में दिखाए गए उदाहरण के तरीके को रेफ़र करता है.

तस्वीरें खींचना

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

कोई फ़ोटो वापस पाने के लिए, Camera.takePicture() तरीके का इस्तेमाल करें. इस तरीके में तीन पैरामीटर होते हैं, जिन्हें कैमरे से डेटा मिलता है. JPEG फ़ॉर्मैट में डेटा पाने के लिए, आपको इमेज का डेटा पाने और उसे किसी फ़ाइल में लिखने के लिए, Camera.PictureCallback इंटरफ़ेस लागू करना होगा. यहां दिए गए कोड में, कैमरे से मिली इमेज को सेव करने के लिए, Camera.PictureCallback इंटरफ़ेस को लागू करने का बुनियादी तरीका बताया गया है.

Kotlin

private val mPicture = Camera.PictureCallback { data, _ ->
    val pictureFile: File = getOutputMediaFile(MEDIA_TYPE_IMAGE) ?: run {
        Log.d(TAG, ("Error creating media file, check storage permissions"))
        return@PictureCallback
    }

    try {
        val fos = FileOutputStream(pictureFile)
        fos.write(data)
        fos.close()
    } catch (e: FileNotFoundException) {
        Log.d(TAG, "File not found: ${e.message}")
    } catch (e: IOException) {
        Log.d(TAG, "Error accessing file: ${e.message}")
    }
}

Java

private PictureCallback mPicture = new PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {

        File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
        if (pictureFile == null){
            Log.d(TAG, "Error creating media file, check storage permissions");
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
    }
};

Camera.takePicture() तरीके को कॉल करके, इमेज कैप्चर करने की प्रोसेस को ट्रिगर करें. यहां दिए गए उदाहरण कोड में, बटन View.OnClickListener से इस तरीके को कॉल करने का तरीका बताया गया है.

Kotlin

val captureButton: Button = findViewById(R.id.button_capture)
captureButton.setOnClickListener {
    // get an image from the camera
    mCamera?.takePicture(null, null, picture)
}

Java

// Add a listener to the Capture button
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(
    new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // get an image from the camera
            mCamera.takePicture(null, null, picture);
        }
    }
);

ध्यान दें: यहां दिए गए उदाहरण में, mPicture मेंबर ऊपर दिए गए कोड के उदाहरण को रेफ़र करता है.

चेतावनी: जब आपका ऐप्लिकेशन Camera ऑब्जेक्ट का इस्तेमाल कर ले, तो Camera.release() को कॉल करके उसे रिलीज़ करना न भूलें! कैमरे को रिलीज़ करने के तरीके के बारे में जानने के लिए, कैमरे को रिलीज़ करना लेख पढ़ें.

वीडियो कैप्चर करना

Android फ़्रेमवर्क का इस्तेमाल करके वीडियो कैप्चर करने के लिए, Camera ऑब्जेक्ट को ध्यान से मैनेज करना और MediaRecorder क्लास के साथ तालमेल बनाना ज़रूरी है. Camera से वीडियो रिकॉर्ड करते समय, आपको Camera.lock() और Camera.unlock() कॉल मैनेज करने होंगे, ताकि MediaRecorder को कैमरा हार्डवेयर का ऐक्सेस मिल सके. इसके अलावा, आपको Camera.open() और Camera.release() कॉल भी मैनेज करने होंगे.

ध्यान दें: Android 4.0 (एपीआई लेवल 14) और इसके बाद के वर्शन पर, Camera.lock() और Camera.unlock() कॉल अपने-आप मैनेज होते हैं.

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

  1. कैमरा खोलना - कैमरा ऑब्जेक्ट का इंस्टेंस पाने के लिए, Camera.open() का इस्तेमाल करें.
  2. कनेक्ट की झलक - Camera.setPreviewDisplay() का इस्तेमाल करके, कैमरे से SurfaceView को कनेक्ट करें. इससे लाइव कैमरे की इमेज की झलक तैयार की जा सकती है.
  3. झलक देखना शुरू करें - लाइव कैमरा इमेज दिखाना शुरू करने के लिए, Camera.startPreview() को कॉल करें.
  4. वीडियो रिकॉर्ड करना शुरू करना - वीडियो को सही तरीके से रिकॉर्ड करने के लिए, यहां दिया गया तरीका इसी क्रम में अपनाएं:
    1. कैमरा अनलॉक करना - MediaRecorder के लिए कैमरा अनलॉक करें. इसके लिए, Camera.unlock() पर कॉल करें.
    2. MediaRecorder को कॉन्फ़िगर करना - इस क्रम में, यहां दिए गए MediaRecorder तरीके कॉल करें. ज़्यादा जानकारी के लिए, MediaRecorder का रेफ़रंस दस्तावेज़ देखें.
      1. setCamera() - वीडियो कैप्चर करने के लिए कैमरा सेट करें. इसके लिए, अपने ऐप्लिकेशन के Camera के मौजूदा इंस्टेंस का इस्तेमाल करें.
      2. setAudioSource() - ऑडियो सोर्स सेट करने के लिए, MediaRecorder.AudioSource.CAMCORDER का इस्तेमाल करें.
      3. setVideoSource() - वीडियो का सोर्स सेट करने के लिए, MediaRecorder.VideoSource.CAMERA का इस्तेमाल करें.
      4. वीडियो का आउटपुट फ़ॉर्मैट और एन्कोडिंग सेट करें. Android 2.2 (एपीआई लेवल 8) और इसके बाद के वर्शन के लिए, MediaRecorder.setProfile तरीके का इस्तेमाल करें. साथ ही, CamcorderProfile.get() का इस्तेमाल करके प्रोफ़ाइल इंस्टेंस पाएं. Android 2.2 से पहले के वर्शन के लिए, आपको वीडियो आउटपुट फ़ॉर्मैट और एन्कोडिंग पैरामीटर सेट करने होंगे:
        1. setOutputFormat() - आउटपुट फ़ॉर्मैट सेट करें, डिफ़ॉल्ट सेटिंग तय करें या MediaRecorder.OutputFormat.MPEG_4.
        2. setAudioEncoder() - साउंड एन्कोडिंग का टाइप सेट करें, डिफ़ॉल्ट सेटिंग तय करें या MediaRecorder.AudioEncoder.AMR_NB.
        3. setVideoEncoder() - वीडियो एन्कोडिंग का टाइप सेट करें, डिफ़ॉल्ट सेटिंग या MediaRecorder.VideoEncoder.MPEG_4_SP तय करें.
      5. setOutputFile() - आउटपुट फ़ाइल सेट करें. इसके लिए, मीडिया फ़ाइलें सेव करना सेक्शन में दिए गए उदाहरण के तरीके से getOutputMediaFile(MEDIA_TYPE_VIDEO).toString() का इस्तेमाल करें.
      6. setPreviewDisplay() - अपने ऐप्लिकेशन के लिए, SurfaceView झलक वाले लेआउट एलिमेंट की जानकारी दें. उसी ऑब्जेक्ट का इस्तेमाल करें जो आपने Connect Preview के लिए तय किया है.

      चेतावनी: आपको कॉन्फ़िगरेशन के इन MediaRecorder तरीकों को इसी क्रम में कॉल करना होगा. ऐसा न करने पर, आपके ऐप्लिकेशन में गड़बड़ियां होंगी और रिकॉर्डिंग नहीं हो पाएगी.

    3. MediaRecorder को तैयार करना - MediaRecorder.prepare() को कॉल करके, दी गई कॉन्फ़िगरेशन सेटिंग के साथ MediaRecorder को तैयार करें.
    4. MediaRecorder शुरू करें - MediaRecorder.start() को कॉल करके वीडियो रिकॉर्ड करना शुरू करें.
  5. वीडियो रिकॉर्ड करना बंद करना - वीडियो रिकॉर्डिंग को पूरा करने के लिए, यहां दिए गए तरीकों को क्रम से कॉल करें:
    1. MediaRecorder को बंद करना - MediaRecorder.stop() को कॉल करके, वीडियो रिकॉर्ड करना बंद करें.
    2. MediaRecorder को रीसेट करना - अगर आप चाहें, तो MediaRecorder.reset() को कॉल करके, रिकॉर्डर से कॉन्फ़िगरेशन सेटिंग हटाएं.
    3. MediaRecorder को रिलीज़ करना - MediaRecorder.release() को कॉल करके, MediaRecorder को रिलीज़ करें.
    4. कैमरा लॉक करना - कैमरे को लॉक करें, ताकि आने वाले समय में MediaRecorder सेशन, Camera.lock() को कॉल करके इसका इस्तेमाल कर सकें. Android 4.0 (एपीआई लेवल 14) और इसके बाद के वर्शन में, इस कॉल की ज़रूरत तब तक नहीं होती, जब तक MediaRecorder.prepare() कॉल पूरा न हो.
  6. झलक दिखाना बंद करना - जब आपकी गतिविधि में कैमरे का इस्तेमाल पूरा हो जाए, तो Camera.stopPreview() का इस्तेमाल करके झलक दिखाना बंद करें.
  7. कैमरा रिलीज़ करना - कैमरे को रिलीज़ करें, ताकि दूसरे ऐप्लिकेशन Camera.release() को कॉल करके इसका इस्तेमाल कर सकें.

ध्यान दें: कैमरे की झलक बनाए बिना भी MediaRecorder का इस्तेमाल किया जा सकता है. साथ ही, इस प्रोसेस के शुरुआती कुछ चरणों को छोड़ा जा सकता है. हालांकि, आम तौर पर उपयोगकर्ता रिकॉर्डिंग शुरू करने से पहले झलक देखना पसंद करते हैं. इसलिए, इस प्रोसेस के बारे में यहां नहीं बताया गया है.

सलाह: अगर आपके ऐप्लिकेशन का इस्तेमाल आम तौर पर वीडियो रिकॉर्ड करने के लिए किया जाता है, तो झलक शुरू करने से पहले setRecordingHint(boolean) को true पर सेट करें. इस सेटिंग की मदद से, रिकॉर्डिंग शुरू करने में लगने वाले समय को कम किया जा सकता है.

MediaRecorder को कॉन्फ़िगर करना

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

Kotlin

private fun prepareVideoRecorder(): Boolean {
    mediaRecorder = MediaRecorder()

    mCamera?.let { camera ->
        // Step 1: Unlock and set camera to MediaRecorder
        camera?.unlock()

        mediaRecorder?.run {
            setCamera(camera)

            // Step 2: Set sources
            setAudioSource(MediaRecorder.AudioSource.CAMCORDER)
            setVideoSource(MediaRecorder.VideoSource.CAMERA)

            // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
            setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH))

            // Step 4: Set output file
            setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString())

            // Step 5: Set the preview output
            setPreviewDisplay(mPreview?.holder?.surface)

            setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
            setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT)
            setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT)


            // Step 6: Prepare configured MediaRecorder
            return try {
                prepare()
                true
            } catch (e: IllegalStateException) {
                Log.d(TAG, "IllegalStateException preparing MediaRecorder: ${e.message}")
                releaseMediaRecorder()
                false
            } catch (e: IOException) {
                Log.d(TAG, "IOException preparing MediaRecorder: ${e.message}")
                releaseMediaRecorder()
                false
            }
        }

    }
    return false
}

Java

private boolean prepareVideoRecorder(){

    mCamera = getCameraInstance();
    mediaRecorder = new MediaRecorder();

    // Step 1: Unlock and set camera to MediaRecorder
    mCamera.unlock();
    mediaRecorder.setCamera(mCamera);

    // Step 2: Set sources
    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
    mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

    // Step 4: Set output file
    mediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());

    // Step 5: Set the preview output
    mediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());

    // Step 6: Prepare configured MediaRecorder
    try {
        mediaRecorder.prepare();
    } catch (IllegalStateException e) {
        Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    } catch (IOException e) {
        Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    }
    return true;
}

Android 2.2 (एपीआई लेवल 8) से पहले, आपको CamcorderProfile का इस्तेमाल करने के बजाय, आउटपुट फ़ॉर्मैट और एन्कोडिंग फ़ॉर्मैट के पैरामीटर सीधे सेट करने होंगे. इस तरीके को यहां दिए गए कोड में दिखाया गया है:

Kotlin

    // Step 3: Set output format and encoding (for versions prior to API Level 8)
    mediaRecorder?.apply {
        setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
        setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT)
        setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT)
    }

Java

    // Step 3: Set output format and encoding (for versions prior to API Level 8)
    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
    mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);

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

MediaRecorder को शुरू और बंद करना

MediaRecorder क्लास का इस्तेमाल करके वीडियो रिकॉर्डिंग शुरू और बंद करते समय, आपको यहां दिए गए क्रम का पालन करना होगा.

  1. Camera.unlock() से कैमरा अनलॉक करें
  2. कोड के ऊपर दिए गए उदाहरण के मुताबिक, MediaRecorder को कॉन्फ़िगर करें
  3. MediaRecorder.start() का इस्तेमाल करके रिकॉर्डिंग शुरू करना
  4. वीडियो रिकॉर्ड करना
  5. MediaRecorder.stop() का इस्तेमाल करके रिकॉर्डिंग बंद करना
  6. MediaRecorder.release() के साथ मीडिया रिकॉर्डर को रिलीज़ करें
  7. Camera.lock() का इस्तेमाल करके कैमरा लॉक करें

यहां दिए गए उदाहरण कोड में, कैमरे और MediaRecorder क्लास का इस्तेमाल करके, वीडियो रिकॉर्डिंग को सही तरीके से शुरू और बंद करने के लिए, बटन को जोड़ने का तरीका बताया गया है.

ध्यान दें: वीडियो रिकॉर्डिंग पूरी करते समय, कैमरे को न छोड़ें. ऐसा करने पर, वीडियो की झलक दिखनी बंद हो जाएगी.

Kotlin

var isRecording = false
val captureButton: Button = findViewById(R.id.button_capture)
captureButton.setOnClickListener {
    if (isRecording) {
        // stop recording and release camera
        mediaRecorder?.stop() // stop the recording
        releaseMediaRecorder() // release the MediaRecorder object
        mCamera?.lock() // take camera access back from MediaRecorder

        // inform the user that recording has stopped
        setCaptureButtonText("Capture")
        isRecording = false
    } else {
        // initialize video camera
        if (prepareVideoRecorder()) {
            // Camera is available and unlocked, MediaRecorder is prepared,
            // now you can start recording
            mediaRecorder?.start()

            // inform the user that recording has started
            setCaptureButtonText("Stop")
            isRecording = true
        } else {
            // prepare didn't work, release the camera
            releaseMediaRecorder()
            // inform user
        }
    }
}

Java

private boolean isRecording = false;

// Add a listener to the Capture button
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(
    new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (isRecording) {
                // stop recording and release camera
                mediaRecorder.stop();  // stop the recording
                releaseMediaRecorder(); // release the MediaRecorder object
                mCamera.lock();         // take camera access back from MediaRecorder

                // inform the user that recording has stopped
                setCaptureButtonText("Capture");
                isRecording = false;
            } else {
                // initialize video camera
                if (prepareVideoRecorder()) {
                    // Camera is available and unlocked, MediaRecorder is prepared,
                    // now you can start recording
                    mediaRecorder.start();

                    // inform the user that recording has started
                    setCaptureButtonText("Stop");
                    isRecording = true;
                } else {
                    // prepare didn't work, release the camera
                    releaseMediaRecorder();
                    // inform user
                }
            }
        }
    }
);

ध्यान दें: ऊपर दिए गए उदाहरण में, prepareVideoRecorder() तरीका, MediaRecorder को कॉन्फ़िगर करना में दिखाए गए उदाहरण कोड को रेफ़र करता है. यह तरीका, कैमरे को लॉक करने, MediaRecorder इंस्टेंस को कॉन्फ़िगर करने, और उसे तैयार करने का काम करता है.

कैमरा रिलीज़ करना

कैमरे एक ऐसा संसाधन हैं जिसे डिवाइस पर मौजूद ऐप्लिकेशन शेयर करते हैं. Camera का इंस्टेंस मिलने के बाद, आपका ऐप्लिकेशन कैमरे का इस्तेमाल कर सकता है. आपको खास तौर पर इस बात का ध्यान रखना होगा कि जब आपका ऐप्लिकेशन कैमरे का इस्तेमाल करना बंद कर दे और जैसे ही आपका ऐप्लिकेशन कुछ समय के लिए बंद (Activity.onPause()) हो जाए, तो कैमरा ऑब्जेक्ट को रिलीज़ कर दिया जाए. अगर आपका ऐप्लिकेशन कैमरे को ठीक से रिलीज़ नहीं करता है, तो कैमरे को ऐक्सेस करने की बाद की सभी कोशिशें नाकाम हो जाएंगी. इनमें आपके ऐप्लिकेशन की कोशिशें भी शामिल हैं. इससे आपका ऐप्लिकेशन या अन्य ऐप्लिकेशन बंद हो सकते हैं.

Camera ऑब्जेक्ट का कोई इंस्टेंस रिलीज़ करने के लिए, Camera.release() तरीके का इस्तेमाल करें. इसके बारे में नीचे दिए गए कोड के उदाहरण में बताया गया है.

Kotlin

class CameraActivity : Activity() {
    private var mCamera: Camera?
    private var preview: SurfaceView?
    private var mediaRecorder: MediaRecorder?

    override fun onPause() {
        super.onPause()
        releaseMediaRecorder() // if you are using MediaRecorder, release it first
        releaseCamera() // release the camera immediately on pause event
    }

    private fun releaseMediaRecorder() {
        mediaRecorder?.reset() // clear recorder configuration
        mediaRecorder?.release() // release the recorder object
        mediaRecorder = null
        mCamera?.lock() // lock camera for later use
    }

    private fun releaseCamera() {
        mCamera?.release() // release the camera for other applications
        mCamera = null
    }
}

Java

public class CameraActivity extends Activity {
    private Camera mCamera;
    private SurfaceView preview;
    private MediaRecorder mediaRecorder;

    ...

    @Override
    protected void onPause() {
        super.onPause();
        releaseMediaRecorder();       // if you are using MediaRecorder, release it first
        releaseCamera();              // release the camera immediately on pause event
    }

    private void releaseMediaRecorder(){
        if (mediaRecorder != null) {
            mediaRecorder.reset();   // clear recorder configuration
            mediaRecorder.release(); // release the recorder object
            mediaRecorder = null;
            mCamera.lock();           // lock camera for later use
        }
    }

    private void releaseCamera(){
        if (mCamera != null){
            mCamera.release();        // release the camera for other applications
            mCamera = null;
        }
    }
}

चेतावनी: अगर आपका ऐप्लिकेशन कैमरे को ठीक से रिलीज़ नहीं करता है, तो कैमरे को ऐक्सेस करने की बाद की सभी कोशिशें नाकाम हो जाएंगी. इनमें आपके ऐप्लिकेशन से की गई कोशिशें भी शामिल हैं. इससे आपका या अन्य ऐप्लिकेशन बंद हो सकते हैं.

मीडिया फ़ाइलें सेव करना

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

  • Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) - इस तरीके से, फ़ोटो और वीडियो सेव करने के लिए स्टैंडर्ड, शेयर की गई, और सुझाई गई जगह की जानकारी मिलती है. यह डायरेक्ट्री शेयर की गई है (सार्वजनिक है). इसलिए, अन्य ऐप्लिकेशन इस जगह पर सेव की गई फ़ाइलों को आसानी से ढूंढ सकते हैं, पढ़ सकते हैं, उनमें बदलाव कर सकते हैं, और उन्हें मिटा सकते हैं. अगर उपयोगकर्ता आपके ऐप्लिकेशन को अनइंस्टॉल कर देता है, तो इस जगह पर सेव की गई मीडिया फ़ाइलें नहीं हटाई जाएंगी. उपयोगकर्ताओं की मौजूदा फ़ोटो और वीडियो में कोई बदलाव न हो, इसके लिए आपको इस डायरेक्ट्री में अपने ऐप्लिकेशन की मीडिया फ़ाइलों के लिए एक सब-डायरेक्ट्री बनानी चाहिए. इसके बारे में यहां दिए गए कोड सैंपल में बताया गया है. यह तरीका, Android 2.2 (एपीआई लेवल 8) में उपलब्ध है. एपीआई के पुराने वर्शन में, मिलती-जुलती कॉल के लिए, शेयर की गई फ़ाइलें सेव करना लेख पढ़ें.
  • Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) - यह तरीका, आपके ऐप्लिकेशन से जुड़ी फ़ोटो और वीडियो को सेव करने के लिए, स्टैंडर्ड जगह की जानकारी दिखाता है. अगर आपका ऐप्लिकेशन अनइंस्टॉल किया जाता है, तो इस जगह पर सेव की गई सभी फ़ाइलें हटा दी जाती हैं. इस जगह पर मौजूद फ़ाइलों के लिए सुरक्षा लागू नहीं की गई है. साथ ही, अन्य ऐप्लिकेशन इन्हें पढ़ सकते हैं, इनमें बदलाव कर सकते हैं, और इन्हें मिटा सकते हैं.

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

Kotlin

val MEDIA_TYPE_IMAGE = 1
val MEDIA_TYPE_VIDEO = 2

/** Create a file Uri for saving an image or video */
private fun getOutputMediaFileUri(type: Int): Uri {
    return Uri.fromFile(getOutputMediaFile(type))
}

/** Create a File for saving an image or video */
private fun getOutputMediaFile(type: Int): File? {
    // To be safe, you should check that the SDCard is mounted
    // using Environment.getExternalStorageState() before doing this.

    val mediaStorageDir = File(
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
            "MyCameraApp"
    )
    // This location works best if you want the created images to be shared
    // between applications and persist after your app has been uninstalled.

    // Create the storage directory if it does not exist
    mediaStorageDir.apply {
        if (!exists()) {
            if (!mkdirs()) {
                Log.d("MyCameraApp", "failed to create directory")
                return null
            }
        }
    }

    // Create a media file name
    val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
    return when (type) {
        MEDIA_TYPE_IMAGE -> {
            File("${mediaStorageDir.path}${File.separator}IMG_$timeStamp.jpg")
        }
        MEDIA_TYPE_VIDEO -> {
            File("${mediaStorageDir.path}${File.separator}VID_$timeStamp.mp4")
        }
        else -> null
    }
}

Java

public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;

/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
      return Uri.fromFile(getOutputMediaFile(type));
}

/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
    // To be safe, you should check that the SDCard is mounted
    // using Environment.getExternalStorageState() before doing this.

    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
              Environment.DIRECTORY_PICTURES), "MyCameraApp");
    // This location works best if you want the created images to be shared
    // between applications and persist after your app has been uninstalled.

    // Create the storage directory if it does not exist
    if (! mediaStorageDir.exists()){
        if (! mediaStorageDir.mkdirs()){
            Log.d("MyCameraApp", "failed to create directory");
            return null;
        }
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File mediaFile;
    if (type == MEDIA_TYPE_IMAGE){
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
        "IMG_"+ timeStamp + ".jpg");
    } else if(type == MEDIA_TYPE_VIDEO) {
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
        "VID_"+ timeStamp + ".mp4");
    } else {
        return null;
    }

    return mediaFile;
}

ध्यान दें: Environment.getExternalStoragePublicDirectory(), Android 2.2 (एपीआई लेवल 8) या इसके बाद के वर्शन में उपलब्ध है. अगर आपको Android के पुराने वर्शन वाले डिवाइसों को टारगेट करना है, तो इसके बजाय Environment.getExternalStorageDirectory() का इस्तेमाल करें. ज़्यादा जानकारी के लिए, शेयर की गई फ़ाइलें सेव करना लेख पढ़ें.

यूआरआई को वर्क प्रोफ़ाइलों के साथ काम करने लायक बनाने के लिए, पहले फ़ाइल यूआरआई को कॉन्टेंट यूआरआई में बदलें. इसके बाद, कॉन्टेंट यूआरआई को Intent के EXTRA_OUTPUT में जोड़ें.

Android डिवाइस पर फ़ाइलें सेव करने के बारे में ज़्यादा जानने के लिए, डेटा स्टोरेज लेख पढ़ें.

कैमरे की सुविधाएं

Android में कैमरे की कई सुविधाएं काम करती हैं. इन्हें कैमरा ऐप्लिकेशन से कंट्रोल किया जा सकता है. जैसे, पिक्चर फ़ॉर्मैट, फ़्लैश मोड, फ़ोकस सेटिंग वगैरह. इस सेक्शन में, कैमरे की सामान्य सुविधाओं की सूची दी गई है. साथ ही, उन्हें इस्तेमाल करने के तरीके के बारे में कम शब्दों में बताया गया है. कैमरे की ज़्यादातर सुविधाओं को Camera.Parameters ऑब्जेक्ट की मदद से ऐक्सेस और सेट किया जा सकता है. हालांकि, कुछ ज़रूरी सुविधाओं के लिए, Camera.Parameters में सामान्य सेटिंग के अलावा और भी सेटिंग की ज़रूरत होती है. इन सुविधाओं के बारे में यहां बताया गया है:

Camera.Parameters से कंट्रोल की जाने वाली सुविधाओं को इस्तेमाल करने के तरीके के बारे में सामान्य जानकारी पाने के लिए, कैमरे की सुविधाओं का इस्तेमाल करना सेक्शन देखें. कैमरा पैरामीटर ऑब्जेक्ट से कंट्रोल की जाने वाली सुविधाओं को इस्तेमाल करने के बारे में ज़्यादा जानकारी पाने के लिए, नीचे दी गई सुविधाओं की सूची में मौजूद लिंक पर जाएं. ये लिंक आपको एपीआई के संदर्भ दस्तावेज़ पर ले जाएंगे.

टेबल 1. कैमरे की सामान्य सुविधाएं, Android एपीआई लेवल के हिसाब से क्रम में लगाई गई हैं. इसमें बताया गया है कि ये सुविधाएं किस एपीआई लेवल में पेश की गई थीं.

सुविधा एपीआई लेवल ब्यौरा
चेहरे की पहचान 14 किसी फ़ोटो में मौजूद इंसानी चेहरों की पहचान करना और उनका इस्तेमाल फ़ोकस, मीटरिंग, और व्हाइट बैलेंस के लिए करना
मीटरिंग एरिया 14 इमेज में एक या उससे ज़्यादा हिस्से चुनें, ताकि व्हाइट बैलेंस का हिसाब लगाया जा सके
किन विषयों पर ध्यान देने की ज़रूरत है 14 इमेज के एक या इससे ज़्यादा हिस्सों को फ़ोकस करने के लिए सेट करना
White Balance Lock 14 व्हाइट बैलेंस अपने-आप अडजस्ट होने की सुविधा को बंद या चालू करना
Exposure Lock 14 एक्सपोज़र अपने-आप अडजस्ट होने की सुविधा को बंद या चालू करना
Video Snapshot 14 वीडियो रिकॉर्ड करते समय फ़ोटो लेना (फ़्रेम ग्रैब)
टाइम लैप्स वीडियो 11 टाइम लैप्स वीडियो रिकॉर्ड करने के लिए, सेट किए गए डिले के साथ फ़्रेम रिकॉर्ड करें
Multiple Cameras 9 एक डिवाइस पर एक से ज़्यादा कैमरे इस्तेमाल करने की सुविधा. इसमें फ़्रंट और रियर कैमरे शामिल हैं
Focus Distance 9 इससे कैमरे और फ़ोकस में दिख रहे ऑब्जेक्ट के बीच की दूरी की जानकारी मिलती है
Zoom 8 इमेज को ज़ूम करने की सुविधा सेट करना
Exposure Compensation 8 लाइट एक्सपोज़र लेवल को बढ़ाएं या घटाएं
GPS Data 5 इमेज के साथ भौगोलिक जगह की जानकारी का डेटा शामिल करना या हटाना
White Balance 5 व्हाइट बैलेंस मोड सेट करें. इससे कैप्चर की गई इमेज में कलर वैल्यू पर असर पड़ता है
Focus Mode 5 कैमरे को किसी सब्जेक्ट पर फ़ोकस करने के लिए सेट करें. जैसे, ऑटोमैटिक, फ़िक्स्ड, मैक्रो या इनफ़िनिटी
Scene Mode 5 फ़ोटोग्राफ़ी की खास स्थितियों के लिए, प्रीसेट मोड लागू करें. जैसे, रात, बीच, बर्फ़ या मोमबत्ती की रोशनी वाले सीन
JPEG Quality 5 JPEG इमेज के लिए कंप्रेसन लेवल सेट करें. इससे इमेज की आउटपुट फ़ाइल की क्वालिटी और साइज़ बढ़ता या घटता है
Flash Mode 5 फ़्लैश को चालू या बंद करना या ऑटोमैटिक सेटिंग का इस्तेमाल करना
Color Effects 5 कैप्चर की गई इमेज पर कोई कलर इफ़ेक्ट लागू करें. जैसे, ब्लैक ऐंड व्हाइट, सेपिया टोन या नेगेटिव.
Anti-Banding 5 JPEG कंप्रेशन की वजह से, कलर ग्रेडिएंट में बैंडिंग के असर को कम करता है
Picture Format 1 इमेज के लिए फ़ाइल फ़ॉर्मैट तय करना
Picture Size 1 सेव की गई इमेज के पिक्सल डाइमेंशन तय करना

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

सुविधा की उपलब्धता की जांच करना

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

कैमरे की सुविधाओं की उपलब्धता देखने के लिए, कैमरे के पैरामीटर ऑब्जेक्ट का इंस्टेंस लें और काम के तरीके देखें. यहां दिए गए कोड सैंपल में, Camera.Parameters ऑब्जेक्ट पाने और यह जांच करने का तरीका बताया गया है कि कैमरा, ऑटोफ़ोकस की सुविधा के साथ काम करता है या नहीं:

Kotlin

val params: Camera.Parameters? = camera?.parameters
val focusModes: List<String>? = params?.supportedFocusModes
if (focusModes?.contains(Camera.Parameters.FOCUS_MODE_AUTO) == true) {
    // Autofocus mode is supported
}

Java

// get Camera parameters
Camera.Parameters params = camera.getParameters();

List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
  // Autofocus mode is supported
}

कैमरे की ज़्यादातर सुविधाओं के लिए, ऊपर बताई गई तकनीक का इस्तेमाल किया जा सकता है. Camera.Parameters ऑब्जेक्ट, getSupported...(), is...Supported() या getMax...() तरीका उपलब्ध कराता है. इससे यह तय किया जाता है कि कोई सुविधा काम करती है या नहीं. अगर काम करती है, तो किस हद तक.

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

कैमरे की सुविधाओं का इस्तेमाल करना

कैमरे की ज़्यादातर सुविधाओं को Camera.Parameters ऑब्जेक्ट का इस्तेमाल करके चालू और कंट्रोल किया जाता है. यह ऑब्जेक्ट पाने के लिए, सबसे पहले Camera ऑब्जेक्ट का इंस्टेंस पाएं. इसके बाद, getParameters() तरीके को कॉल करें और दिखाए गए पैरामीटर ऑब्जेक्ट को बदलें. इसके बाद, उसे वापस कैमरा ऑब्जेक्ट में सेट करें. इसके बारे में यहां दिए गए उदाहरण कोड में बताया गया है:

Kotlin

val params: Camera.Parameters? = camera?.parameters
params?.focusMode = Camera.Parameters.FOCUS_MODE_AUTO
camera?.parameters = params

Java

// get Camera parameters
Camera.Parameters params = camera.getParameters();
// set the focus mode
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// set Camera parameters
camera.setParameters(params);

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

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

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

  • मीटरिंग और फ़ोकस एरिया
  • चेहरे की पहचान
  • टाइम लैप्स वीडियो

इन सुविधाओं को लागू करने के तरीके के बारे में खास जानकारी, यहां दी गई है.

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

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

मीटरिंग और फ़ोकस के लिए एरिया, कैमरे की अन्य सुविधाओं की तरह ही काम करते हैं. इन्हें Camera.Parameters ऑब्जेक्ट में मौजूद तरीकों से कंट्रोल किया जाता है. यहां दिए गए कोड से, Camera के इंस्टेंस के लिए, लाइट मीटरिंग के दो हिस्सों को सेट करने का तरीका पता चलता है:

Kotlin

// Create an instance of Camera
camera = getCameraInstance()

// set Camera parameters
val params: Camera.Parameters? = camera?.parameters

params?.apply {
    if (maxNumMeteringAreas > 0) { // check that metering areas are supported
        meteringAreas = ArrayList<Camera.Area>().apply {
            val areaRect1 = Rect(-100, -100, 100, 100) // specify an area in center of image
            add(Camera.Area(areaRect1, 600)) // set weight to 60%
            val areaRect2 = Rect(800, -1000, 1000, -800) // specify an area in upper right of image
            add(Camera.Area(areaRect2, 400)) // set weight to 40%
        }
    }
    camera?.parameters = this
}

Java

// Create an instance of Camera
camera = getCameraInstance();

// set Camera parameters
Camera.Parameters params = camera.getParameters();

if (params.getMaxNumMeteringAreas() > 0){ // check that metering areas are supported
    List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();

    Rect areaRect1 = new Rect(-100, -100, 100, 100);    // specify an area in center of image
    meteringAreas.add(new Camera.Area(areaRect1, 600)); // set weight to 60%
    Rect areaRect2 = new Rect(800, -1000, 1000, -800);  // specify an area in upper right of image
    meteringAreas.add(new Camera.Area(areaRect2, 400)); // set weight to 40%
    params.setMeteringAreas(meteringAreas);
}

camera.setParameters(params);

Camera.Area ऑब्जेक्ट में दो डेटा पैरामीटर होते हैं: कैमरे के फ़ील्ड ऑफ़ व्यू (कैमरे से दिख रहा व्यू) में किसी इलाके की जानकारी देने के लिए Rect ऑब्जेक्ट और वेट वैल्यू. इससे कैमरे को पता चलता है कि लाइट मीटरिंग या फ़ोकस कैलकुलेशन में इस इलाके को कितनी अहमियत दी जानी चाहिए.

Camera.Area ऑब्जेक्ट में मौजूद Rect फ़ील्ड, 2000 x 2000 यूनिट ग्रिड पर मैप किए गए रेक्टैंगल शेप के बारे में बताता है. निर्देशांक -1000, -1000, कैमरे से ली गई इमेज के सबसे ऊपर, बाएं कोने को दिखाते हैं. वहीं, निर्देशांक 1000, 1000, कैमरे से ली गई इमेज के सबसे नीचे, दाएं कोने को दिखाते हैं. इसके बारे में नीचे दी गई इमेज में बताया गया है.

पहली इमेज. लाल लाइनें, कैमरे की झलक में Camera.Area तय करने के लिए, कोऑर्डिनेट सिस्टम को दिखाती हैं. नीला बॉक्स, कैमरे के फ़ोकस एरिया की जगह और आकार दिखाता है. इसमें Rect की वैल्यू 333,333,667,667 है.

इस कोऑर्डिनेट सिस्टम की सीमाएं, हमेशा कैमरे की झलक में दिखने वाली इमेज के बाहरी किनारे से मेल खाती हैं. साथ ही, ये ज़ूम करने के लेवल के साथ छोटी या बड़ी नहीं होती हैं. इसी तरह, Camera.setDisplayOrientation() का इस्तेमाल करके इमेज की झलक को घुमाने से, कोऑर्डिनेट सिस्टम फिर से मैप नहीं होता.

चेहरे की पहचान

जिन फ़ोटो में लोग शामिल होते हैं उनमें चेहरे सबसे अहम हिस्सा होते हैं. फ़ोटो लेते समय, फ़ोकस और व्हाइट बैलेंस, दोनों को तय करने के लिए चेहरों का इस्तेमाल किया जाना चाहिए. Android 4.0 (एपीआई लेवल 14) फ़्रेमवर्क, चेहरे की पहचान करने वाली टेक्नोलॉजी का इस्तेमाल करके, चेहरे की पहचान करने और पिक्चर की सेटिंग का हिसाब लगाने के लिए एपीआई उपलब्ध कराता है.

ध्यान दें: चेहरे की पहचान करने की सुविधा चालू होने पर, setWhiteBalance(String), setFocusAreas(List<Camera.Area>), और setMeteringAreas(List<Camera.Area>) का कोई असर नहीं होता.

अपने कैमरा ऐप्लिकेशन में चेहरे की पहचान करने की सुविधा का इस्तेमाल करने के लिए, आपको कुछ सामान्य चरणों को पूरा करना होगा:

  • देखें कि डिवाइस पर चेहरे की पहचान करने की सुविधा काम करती है या नहीं
  • चेहरे की पहचान करने वाला लिसनर बनाना
  • अपने कैमरा ऑब्जेक्ट में, चेहरे की पहचान करने वाला लिसनर जोड़ें
  • झलक के बाद, चेहरे की पहचान करने की सुविधा चालू करें. साथ ही, झलक के हर बार रीस्टार्ट होने के बाद भी ऐसा करें

चेहरे की पहचान करने की सुविधा, सभी डिवाइसों पर काम नहीं करती. getMaxNumDetectedFaces() पर कॉल करके, यह पता लगाया जा सकता है कि यह सुविधा काम करती है या नहीं. इस जांच का एक उदाहरण, नीचे दिए गए startFaceDetection() सैंपल तरीके में दिखाया गया है.

चेहरे की पहचान होने पर सूचना पाने और उसका जवाब देने के लिए, आपके कैमरा ऐप्लिकेशन में चेहरे की पहचान करने वाले इवेंट के लिए, लिसनर सेट होना चाहिए. ऐसा करने के लिए, आपको एक लिसनर क्लास बनानी होगी, जो Camera.FaceDetectionListener इंटरफ़ेस को लागू करती हो. इसके बारे में यहां दिए गए उदाहरण कोड में बताया गया है.

Kotlin

internal class MyFaceDetectionListener : Camera.FaceDetectionListener {

    override fun onFaceDetection(faces: Array<Camera.Face>, camera: Camera) {
        if (faces.isNotEmpty()) {
            Log.d("FaceDetection", ("face detected: ${faces.size}" +
                    " Face 1 Location X: ${faces[0].rect.centerX()}" +
                    "Y: ${faces[0].rect.centerY()}"))
        }
    }
}

Java

class MyFaceDetectionListener implements Camera.FaceDetectionListener {

    @Override
    public void onFaceDetection(Face[] faces, Camera camera) {
        if (faces.length > 0){
            Log.d("FaceDetection", "face detected: "+ faces.length +
                    " Face 1 Location X: " + faces[0].rect.centerX() +
                    "Y: " + faces[0].rect.centerY() );
        }
    }
}

यह क्लास बनाने के बाद, इसे अपने ऐप्लिकेशन के Camera ऑब्जेक्ट में सेट करें, जैसा कि नीचे दिए गए उदाहरण कोड में दिखाया गया है:

Kotlin

camera?.setFaceDetectionListener(MyFaceDetectionListener())

Java

camera.setFaceDetectionListener(new MyFaceDetectionListener());

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

Kotlin

fun startFaceDetection() {
    // Try starting Face Detection
    val params = mCamera?.parameters
    // start face detection only *after* preview has started

    params?.apply {
        if (maxNumDetectedFaces > 0) {
            // camera supports face detection, so can start it:
            mCamera?.startFaceDetection()
        }
    }
}

Java

public void startFaceDetection(){
    // Try starting Face Detection
    Camera.Parameters params = mCamera.getParameters();

    // start face detection only *after* preview has started
    if (params.getMaxNumDetectedFaces() > 0){
        // camera supports face detection, so can start it:
        mCamera.startFaceDetection();
    }
}

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

Kotlin

override fun surfaceCreated(holder: SurfaceHolder) {
    try {
        mCamera.setPreviewDisplay(holder)
        mCamera.startPreview()

        startFaceDetection() // start face detection feature
    } catch (e: IOException) {
        Log.d(TAG, "Error setting camera preview: ${e.message}")
    }
}

override fun surfaceChanged(holder: SurfaceHolder, format: Int, w: Int, h: Int) {
    if (holder.surface == null) {
        // preview surface does not exist
        Log.d(TAG, "holder.getSurface() == null")
        return
    }
    try {
        mCamera.stopPreview()
    } catch (e: Exception) {
        // ignore: tried to stop a non-existent preview
        Log.d(TAG, "Error stopping camera preview: ${e.message}")
    }
    try {
        mCamera.setPreviewDisplay(holder)
        mCamera.startPreview()

        startFaceDetection() // re-start face detection feature
    } catch (e: Exception) {
        // ignore: tried to stop a non-existent preview
        Log.d(TAG, "Error starting camera preview: ${e.message}")
    }
}

Java

public void surfaceCreated(SurfaceHolder holder) {
    try {
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();

        startFaceDetection(); // start face detection feature

    } catch (IOException e) {
        Log.d(TAG, "Error setting camera preview: " + e.getMessage());
    }
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

    if (holder.getSurface() == null){
        // preview surface does not exist
        Log.d(TAG, "holder.getSurface() == null");
        return;
    }

    try {
        mCamera.stopPreview();

    } catch (Exception e){
        // ignore: tried to stop a non-existent preview
        Log.d(TAG, "Error stopping camera preview: " + e.getMessage());
    }

    try {
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();

        startFaceDetection(); // re-start face detection feature

    } catch (Exception e){
        // ignore: tried to stop a non-existent preview
        Log.d(TAG, "Error starting camera preview: " + e.getMessage());
    }
}

ध्यान दें: startPreview() को कॉल करने के बाद, इस तरीके को कॉल करना न भूलें. अपने कैमरा ऐप्लिकेशन की मुख्य गतिविधि के onCreate() तरीके में, चेहरे की पहचान करने की सुविधा शुरू करने की कोशिश न करें. ऐसा इसलिए, क्योंकि आपके ऐप्लिकेशन के लागू होने के इस चरण में झलक उपलब्ध नहीं होती.

टाइम लैप्स वीडियो

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

MediaRecorder की मदद से टाइम लैप्स वीडियो रिकॉर्ड करने के लिए, आपको रिकॉर्डर ऑब्जेक्ट को इस तरह कॉन्फ़िगर करना होगा जैसे कि कोई सामान्य वीडियो रिकॉर्ड किया जा रहा हो. इसके लिए, कैप्चर किए गए फ़्रेम प्रति सेकंड को कम संख्या पर सेट करें और टाइम लैप्स की क्वालिटी की सेटिंग में से किसी एक का इस्तेमाल करें. इसके बारे में नीचे दिए गए कोड के उदाहरण में बताया गया है.

Kotlin

mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH))
mediaRecorder.setCaptureRate(0.1) // capture a frame every 10 seconds

Java

// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH));
...
// Step 5.5: Set the video capture rate to a low number
mediaRecorder.setCaptureRate(0.1); // capture a frame every 10 seconds

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

Camera2Video और HdrViewfinder सैंपल से, इस पेज पर बताए गए एपीआई के इस्तेमाल के बारे में ज़्यादा जानकारी मिलती है.

कैमरे के ऐसे फ़ील्ड जिनके लिए अनुमति ज़रूरी है

Android 10 (एपीआई लेवल 29) या इसके बाद के वर्शन पर काम करने वाले ऐप्लिकेशन के पास, CAMERA की अनुमति होनी चाहिए. इससे वे उन फ़ील्ड की वैल्यू ऐक्सेस कर पाएंगे जिन्हें getCameraCharacteristics() तरीका दिखाता है:

  • LENS_POSE_ROTATION
  • LENS_POSE_TRANSLATION
  • LENS_INTRINSIC_CALIBRATION
  • LENS_RADIAL_DISTORTION
  • LENS_POSE_REFERENCE
  • LENS_DISTORTION
  • LENS_INFO_HYPERFOCAL_DISTANCE
  • LENS_INFO_MINIMUM_FOCUS_DISTANCE
  • SENSOR_REFERENCE_ILLUMINANT1
  • SENSOR_REFERENCE_ILLUMINANT2
  • SENSOR_CALIBRATION_TRANSFORM1
  • SENSOR_CALIBRATION_TRANSFORM2
  • SENSOR_COLOR_TRANSFORM1
  • SENSOR_COLOR_TRANSFORM2
  • SENSOR_FORWARD_MATRIX1
  • SENSOR_FORWARD_MATRIX2

कुछ और सैंपल कोड

सैंपल के तौर पर मिले ऐप्लिकेशन डाउनलोड करने के लिए, Camera2Basic सैंपल और CameraX का आधिकारिक सैंपल ऐप्लिकेशन देखें.