Camera API

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

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

इसी विषय से जुड़े इन संसाधनों को देखें:

ज़रूरी बातें

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

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

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

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

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

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

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 एपीआई का इस्तेमाल करने का सुझाव दिया जाता है.

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

  • कैमरे का पता लगाना और उसे ऐक्सेस करना - कैमरे मौजूद हैं या नहीं, यह पता लगाने और उन्हें ऐक्सेस करने का अनुरोध करने के लिए कोड बनाएं.
  • Preview Class बनाना - कैमरा प्रीव्यू क्लास बनाएं, जो 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. कैमरा अनलॉक करना - Camera.unlock() को कॉल करके, MediaRecorder के लिए कैमरा अनलॉक करें.
    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() - Set the sound encoding type, specify the default setting or MediaRecorder.AudioEncoder.AMR_NB.
        3. setVideoEncoder() - वीडियो एन्कोडिंग का टाइप सेट करें, डिफ़ॉल्ट सेटिंग तय करें या MediaRecorder.VideoEncoder.MPEG_4_SP.
      5. setOutputFile() - आउटपुट फ़ाइल सेट करें. इसके लिए, मीडिया फ़ाइलें सेव करना सेक्शन में दिए गए उदाहरण के तरीके में getOutputMediaFile(MEDIA_TYPE_VIDEO).toString() का इस्तेमाल करें.
      6. setPreviewDisplay() - अपने ऐप्लिकेशन के लिए, SurfaceView झलक दिखाने वाले लेआउट एलिमेंट के बारे में बताएं. कनेक्ट करने की झलक के लिए, उसी ऑब्जेक्ट का इस्तेमाल करें जिसे आपने तय किया था.

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

    3. MediaRecorder तैयार करें - MediaRecorder.prepare() को कॉल करके, दी गई कॉन्फ़िगरेशन सेटिंग के साथ MediaRecorder तैयार करें.
    4. MediaRecorder शुरू करें - MediaRecorder.start() को कॉल करके वीडियो रिकॉर्ड करना शुरू करें.
  5. वीडियो रिकॉर्डिंग बंद करना - वीडियो रिकॉर्डिंग को पूरा करने के लिए, यहां दिए गए तरीकों को इसी क्रम में कॉल करें:
    1. Stop 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. Release Camera - कैमरे को रिलीज़ करें, ताकि अन्य ऐप्लिकेशन 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 का इंस्टेंस मिलने के बाद, आपका ऐप्लिकेशन कैमरे का इस्तेमाल कर सकता है. जब आपका ऐप्लिकेशन कैमरे का इस्तेमाल करना बंद कर दे, तब आपको कैमरे के ऑब्जेक्ट को रिलीज़ करने के लिए खास तौर पर ध्यान रखना होगा. साथ ही, जैसे ही आपका ऐप्लिकेशन रुक जाए (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) - This method returns the standard, shared and recommended location for saving pictures and videos. यह डायरेक्ट्री शेयर की गई है (सार्वजनिक है). इसलिए, अन्य ऐप्लिकेशन इस जगह पर सेव की गई फ़ाइलों को आसानी से ढूंढ सकते हैं, पढ़ सकते हैं, उनमें बदलाव कर सकते हैं, और उन्हें मिटा सकते हैं. अगर उपयोगकर्ता आपका ऐप्लिकेशन अनइंस्टॉल करता है, तो इस जगह पर सेव की गई मीडिया फ़ाइलें नहीं हटाई जाएंगी. उपयोगकर्ताओं की मौजूदा फ़ोटो और वीडियो में कोई बदलाव न हो, इसके लिए आपको इस डायरेक्ट्री में अपने ऐप्लिकेशन की मीडिया फ़ाइलों के लिए एक सब-डायरेक्ट्री बनानी चाहिए. इसके लिए, यहाँ दिए गए कोड सैंपल का इस्तेमाल करें. यह तरीका Android 2.2 (एपीआई लेवल 8) में उपलब्ध है. एपीआई के पुराने वर्शन में इसी तरह के कॉल के लिए, शेयर की गई फ़ाइलें सेव करना लेख पढ़ें.
  • Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) - This method returns a standard location for saving pictures and videos which are associated with your application. अगर आपका ऐप्लिकेशन अनइंस्टॉल कर दिया जाता है, तो इस जगह पर सेव की गई सभी फ़ाइलें हटा दी जाती हैं. इस जगह पर मौजूद फ़ाइलों के लिए सुरक्षा लागू नहीं की जाती. साथ ही, अन्य ऐप्लिकेशन इन्हें पढ़ सकते हैं, इनमें बदलाव कर सकते हैं, और इन्हें मिटा सकते हैं.

यहां दिए गए उदाहरण कोड में, मीडिया फ़ाइल के लिए 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 से कंट्रोल की जाने वाली सुविधाओं को इस्तेमाल करने के तरीके के बारे में सामान्य जानकारी पाने के लिए, कैमरे की सुविधाओं का इस्तेमाल करना सेक्शन देखें. कैमरा पैरामीटर ऑब्जेक्ट के ज़रिए कंट्रोल की जाने वाली सुविधाओं को इस्तेमाल करने के बारे में ज़्यादा जानकारी पाने के लिए, एपीआई के रेफ़रंस दस्तावेज़ में मौजूद सुविधाओं की सूची में दिए गए लिंक पर जाएं.

पहली टेबल. कैमरे की सामान्य सुविधाओं को 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 ऑब्जेक्ट, कैमरे के फ़ील्ड ऑफ़ व्यू में किसी जगह को तय करने के लिए होता है. दूसरा, वज़न की वैल्यू होती है. इससे कैमरे को पता चलता है कि लाइट मीटरिंग या फ़ोकस कैलकुलेशन में इस जगह को कितना महत्व दिया जाना चाहिए.

Rect ऑब्जेक्ट में मौजूद Rect फ़ील्ड, 2000 x 2000 यूनिट ग्रिड पर मैप किए गए रेक्टैंगल के आकार के बारे में बताता है.Camera.Area निर्देशांक -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 का आधिकारिक सैंपल ऐप्लिकेशन देखें.