एंड्रॉइड में कैमरा कार्यक्षमता: CameraX बनाम Camera2 बनाम इंटेंट
यह उदाहरण कैमरे के साथ काम करने के तीन दृष्टिकोणों को कवर करता है: सरल इंटेंट (सबसे आसान), CameraX (अनुशंसित आधुनिक), और Camera2 (निम्न-स्तरीय नियंत्रण)।
चरण 1: नया प्रोजेक्ट बनाएं
एंड्रॉइड स्टूडियो में File → New Project चुनें।
चरण 2: लेआउट (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.camera.view.PreviewView
android:id="@+id/previewView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="@+id/btnCapture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="50dp"
android:text="फोटो लें"
android:textSize="18sp"
android:paddingHorizontal="32dp"
android:paddingVertical="12dp" />
<ImageView
android:id="@+id/imageViewCaptured"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_margin="16dp"
android:scaleType="centerCrop"
android:visibility="gone" />
</RelativeLayout>
चरण 3: CameraX कार्यान्वयन (अनुशंसित - build.gradle में निर्भरताएं जोड़ें)
// build.gradle (Module: app)
dependencies {
def camerax_version = "1.3.0"
implementation "androidx.camera:camera-core:${camerax_version}"
implementation "androidx.camera:camera-camera2:${camerax_version}"
implementation "androidx.camera:camera-lifecycle:${camerax_version}"
implementation "androidx.camera:camera-view:${camerax_version}"
implementation "androidx.camera:camera-video:${camerax_version}"
}
import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.widget.Button
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.common.util.concurrent.ListenableFuture
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
class MainActivity : AppCompatActivity() {
private lateinit var previewView: PreviewView
private lateinit var btnCapture: Button
private lateinit var imageViewCaptured: ImageView
private var imageCapture: ImageCapture? = null
private val cameraExecutor = Executors.newSingleThreadExecutor()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = "CameraX Demo"
previewView = findViewById(R.id.previewView)
btnCapture = findViewById(R.id.btnCapture)
imageViewCaptured = findViewById(R.id.imageViewCaptured)
if (allPermissionsGranted()) {
startCamera()
} else {
ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS)
}
btnCapture.setOnClickListener { takePhoto() }
}
private fun startCamera() {
val cameraProviderFuture: ListenableFuture =
ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({
val cameraProvider = cameraProviderFuture.get()
bindCameraUseCases(cameraProvider)
}, ContextCompat.getMainExecutor(this))
}
private fun bindCameraUseCases(cameraProvider: ProcessCameraProvider) {
// प्रीव्यू
val preview = Preview.Builder().build().also {
it.setSurfaceProvider(previewView.surfaceProvider)
}
// छवि कैप्चर
imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.build()
// कैमरा सेलेक्टर (बैक कैमरा)
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
// उपयोग केस बाइंड करें
try {
cameraProvider.unbindAll()
cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture)
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun takePhoto() {
val imageCapture = imageCapture ?: return
// MediaStore में सहेजें
val contentValues = android.content.ContentValues().apply {
put(android.provider.MediaStore.Images.Media.TITLE, "CameraX Photo")
put(android.provider.MediaStore.Images.Media.DESCRIPTION, "CameraX से कैप्चर किया गया")
}
val outputOptions = ImageCapture.OutputFileOptions
.Builder(contentResolver,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
contentValues)
.build()
imageCapture.takePicture(
outputOptions,
ContextCompat.getMainExecutor(this),
object : ImageCapture.OnImageSavedCallback {
override fun onError(exc: ImageCaptureException) {
Toast.makeText(this@MainActivity, "कैप्चर विफल: ${exc.message}", Toast.LENGTH_SHORT).show()
}
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
val uri = output.savedUri ?: return
imageViewCaptured.visibility = android.view.View.VISIBLE
imageViewCaptured.setImageURI(uri)
Toast.makeText(this@MainActivity, "फोटो सहेजी गई", Toast.LENGTH_SHORT).show()
}
}
)
}
private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
ContextCompat.checkSelfPermission(baseContext, it) == PackageManager.PERMISSION_GRANTED
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == REQUEST_CODE_PERMISSIONS) {
if (allPermissionsGranted()) {
startCamera()
} else {
Toast.makeText(this, "कैमरा अनुमति आवश्यक", Toast.LENGTH_SHORT).show()
finish()
}
}
}
override fun onDestroy() {
super.onDestroy()
cameraExecutor.shutdown()
}
companion object {
private const val REQUEST_CODE_PERMISSIONS = 10
private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
}
}
चरण 4: सरल इंटेंट दृष्टिकोण (CameraX के बिना)
import android.content.ContentValues
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.widget.Button
import android.widget.ImageView
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
class SimpleCameraActivity : AppCompatActivity() {
private lateinit var imageView: ImageView
private var imageUri: Uri? = null
// आधुनिक कैमरा इंटेंट
private val takePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) { success ->
if (success) {
imageUri?.let { imageView.setImageURI(it) }
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_simple_camera)
imageView = findViewById(R.id.imageView)
findViewById
चरण 5: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.camerawork">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<uses-feature android:name="android.hardware.camera" android:required="true" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
तीन दृष्टिकोणों की तुलना:
| पहलू | कैमरा इंटेंट | CameraX | Camera2 |
|---|---|---|---|
| जटिलता | बहुत कम | कम | उच्च |
| UI अनुकूलन | कोई नहीं (सिस्टम UI) | पूर्ण (PreviewView) | पूर्ण (SurfaceView/TextureView) |
| कैमरा नियंत्रण | कोई नहीं | अच्छा (ज़ूम, फ्लैश, फोकस) | पूर्ण (सभी पैरामीटर) |
| छवि गुणवत्ता | सिस्टम डिफ़ॉल्ट | उच्च (कॉन्फ़िगरेबल) | अधिकतम (RAW समर्थन) |
| वीडियो रिकॉर्डिंग | हाँ (इंटेंट) | हाँ (VideoCapture) | हाँ (MediaRecorder) |
| ML Kit एकीकरण | नहीं | हाँ (ImageAnalysis) | मैन्युअल |
| जीवनचक्र प्रबंधन | स्वचालित | स्वचालित (LifecycleOwner) | मैन्युअल |
| उपयोग का मामला | सरल फोटो लेना | अधिकांश ऐप्स (अनुशंसित) | उन्नत कैमरा ऐप्स |
CameraX उन्नत सुविधाएं:
- ImageAnalysis: फ्रेम-दर-फ्रेम विश्लेषण (ML Kit, बारकोड स्कैनिंग)
- VideoCapture: उच्च गुणवत्ता वाली वीडियो रिकॉर्डिंग
- Extensions API: HDR, नाइट मोड, बोकेह, फेस रीटच (डिवाइस-विशिष्ट)
- कैमरा सेलेक्टर: फ्रंट/बैक कैमरा आसानी से स्विच करें
- टॉर्च/फ्लैश नियंत्रण: `cameraControl.enableTorch(true)`
CameraX में कैमरा स्विच करना:
private var currentCameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
fun switchCamera() {
currentCameraSelector = if (currentCameraSelector == CameraSelector.DEFAULT_BACK_CAMERA) {
CameraSelector.DEFAULT_FRONT_CAMERA
} else {
CameraSelector.DEFAULT_BACK_CAMERA
}
// पुनः बाइंड करें
cameraProvider.unbindAll()
cameraProvider.bindToLifecycle(this, currentCameraSelector, preview, imageCapture)
}