মনে রাখবেন: এই পৃষ্ঠা Camera2 প্যাকেজকে রেফার করে। আপনার অ্যাপের জন্য Camera2 থেকে নির্দিষ্ট, লো-লেভেল ফিচারের প্রয়োজন না হলে, আমরা CameraX ব্যবহার করার সাজেশন দিই। CameraX এবং Camera2, দুটিই Android 5.0 (API লেভেল ২১) এবং তার পরবর্তী যেকোনও ভার্সনে কাজ করে।
অনেক আধুনিক Android ডিভাইসের সামনে, পিছনে বা ডিভাইসের দুই দিকেই দুটি বা তার বেশি ক্যামেরা থাকে। প্রতিটি লেন্সের অনন্য ক্ষমতা থাকতে পারে, যেমন বার্স্ট ক্যাপচার, ম্যানুয়াল কন্ট্রোল বা মোশন ট্র্যাকিং। চেক জমা দেওয়ার অ্যাপ শুধুমাত্র প্রথম রিয়ার-ফেসিং ক্যামেরা ব্যবহার করতে পারে, যেখানে সোশ্যাল মিডিয়া অ্যাপ ডিফল্ট হিসেবে ফ্রন্ট-ফেসিং ক্যামেরা ব্যবহার করতে পারে, তবে ব্যবহারকারীকে উপলভ্য সব লেন্সের মধ্যে পাল্টানোর বিকল্প দেয়। এটি তাদের পছন্দও মনে রাখতে পারে।
এই পৃষ্ঠায় ক্যামেরা লেন্স ও সেগুলির ক্ষমতা কীভাবে তালিকাভুক্ত করতে হয় তা কভার করা হয়েছে যাতে আপনি নিজের অ্যাপের মধ্যে থেকে সিদ্ধান্ত নিতে পারেন যে কোনও নির্দিষ্ট পরিস্থিতিতে কোন লেন্স ব্যবহার করতে হবে। নিম্নলিখিত কোড স্নিপেট সব ক্যামেরার তালিকা ফিরিয়ে আনে এবং সেগুলির উপর ইটারেট করে:
Kotlin
try { val cameraIdList = cameraManager.cameraIdList // may be empty // iterate over available camera devices for (cameraId in cameraIdList) { val characteristics = cameraManager.getCameraCharacteristics(cameraId) val cameraLensFacing = characteristics.get(CameraCharacteristics.LENS_FACING) val cameraCapabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES) // check if the selected camera device supports basic features // ensures backward compatibility with the original Camera API val isBackwardCompatible = cameraCapabilities?.contains( CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) ?: false ... } } catch (e: CameraAccessException) { e.message?.let { Log.e(TAG, it) } ... }
জাভা
try { String[] cameraIdList = cameraManager.getCameraIdList(); // may be empty // iterate over available camera devices for (String cameraId : cameraIdList) { CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId); int cameraLensFacing = characteristics.get(CameraCharacteristics.LENS_FACING); int[] cameraCapabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES); // check if the selected camera device supports basic features // ensures backward compatibility with the original Camera API boolean isBackwardCompatible = false; for (int capability : cameraCapabilities) { if (capability == CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) { isBackwardCompatible = true; break; } } ... } } catch (CameraAccessException e) { Log.e(TAG, e.getMessage()); ... }
cameraLensFacing ভেরিয়েবলটি ডিভাইসের স্ক্রিনের সাপেক্ষে ক্যামেরা কোন দিকে মুখ করে আছে তা বর্ণনা করে
এবং এর নিম্নলিখিত ভ্যালুগুলির মধ্যে একটি থাকে:
CameraMetadata.LENS_FACING_FRONTCameraMetadata.LENS_FACING_BACKCameraMetadata.LENS_FACING_EXTERNAL
লেন্স-ফেসিং কনফিগারেশন সম্পর্কে আরও জানতে, CameraCharacteristics.LENS_FACING দেখুন।
পূর্ববর্তী কোড স্যাম্পেল থেকে cameraCapabilities ভেরিয়েবলে
বিবিধ ক্ষমতা সম্পর্কে তথ্য রয়েছে, যার মধ্যে ক্যামেরাটি
আউটপুট হিসাবে স্ট্যান্ডার্ড ফ্রেম তৈরি করতে সক্ষম কিনা (যেমন, শুধুমাত্র
ডেপথ সেন্সর ডেটার বিপরীতে)। আপনি দেখতে পারেন যে
CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
ক্যামেরার তালিকাভুক্ত ক্ষমতার মধ্যে একটি কিনা, যা
isBackwardCompatible-এ ফ্ল্যাগ হিসেবে স্টোর করা আছে।
বুদ্ধিদীপ্ত ডিফল্ট বেছে নিন
আপনার অ্যাপে, আপনি সম্ভবত ডিফল্ট হিসেবে একটি নির্দিষ্ট ক্যামেরা খুলতে চান (যদি এটি উপলভ্য থাকে)। যেমন, সেলফি অ্যাপ সম্ভবত সামনের ক্যামেরা খোলে, যেখানে অগমেন্টেড রিয়েলিটি অ্যাপ পিছনের ক্যামেরা দিয়ে শুরু করতে পারে। নিম্নলিখিত ফাংশনটি প্রথম ক্যামেরাটি ফেরত দেয় যা একটি নির্দিষ্ট দিকে মুখ করে থাকে:
Kotlin
fun getFirstCameraIdFacing(cameraManager: CameraManager, facing: Int = CameraMetadata.LENS_FACING_BACK): String? { try { // Get list of all compatible cameras val cameraIds = cameraManager.cameraIdList.filter { val characteristics = cameraManager.getCameraCharacteristics(it) val capabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES) capabilities?.contains( CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) ?: false } // Iterate over the list of cameras and return the first one matching desired // lens-facing configuration cameraIds.forEach { val characteristics = cameraManager.getCameraCharacteristics(it) if (characteristics.get(CameraCharacteristics.LENS_FACING) == facing) { return it } } // If no camera matched desired orientation, return the first one from the list return cameraIds.firstOrNull() } catch (e: CameraAccessException) { e.message?.let { Log.e(TAG, it) } } }
জাভা
public String getFirstCameraIdFacing(CameraManager cameraManager, @Nullable Integer facing) { if (facing == null) facing = CameraMetadata.LENS_FACING_BACK; String cameraId = null; try { // Get a list of all compatible cameras String[] cameraIdList = cameraManager.getCameraIdList(); // Iterate over the list of cameras and return the first one matching desired // lens-facing configuration and backward compatibility for (String id : cameraIdList) { CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(id); int[] capabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES); for (int capability : capabilities) { if (capability == CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE && characteristics.get(CameraCharacteristics.LENS_FACING).equals(facing)) { cameraId = id; break; } } } // If no camera matches the desired orientation, return the first one from the list cameraId = cameraIdList[0]; } catch (CameraAccessException e) { Log.e(TAG, "getFirstCameraIdFacing: " + e.getMessage()); } return cameraId; }
ক্যামেরা পাল্টানোর সুবিধা চালু করুন
অনেক ক্যামেরা অ্যাপ ব্যবহারকারীদের ক্যামেরা পরিবর্তন করার বিকল্প দেয়:
অনেক ডিভাইসে একাধিক ক্যামেরা থাকে যেগুলি একই দিকে মুখ করে থাকে। এমনকি কিছু ডিভাইসে এক্সটার্নাল USB ক্যামেরা আছে। ব্যবহারকারীদের এমন একটি UI প্রদান করতে যা তাদের বিভিন্ন ফেসিং ক্যামেরার মধ্যে পরিবর্তন করতে দেয়, প্রতিটি সম্ভাব্য লেন্স-ফেসিং কনফিগারেশনের জন্য প্রথম উপলভ্য ক্যামেরা বেছে নিন।
পরবর্তী ক্যামেরা বেছে নেওয়ার জন্য কোনও সর্বজনীন লজিক না থাকলেও, নিম্নলিখিত কোডটি বেশিরভাগ ব্যবহারের ক্ষেত্রে কাজ করে:
Kotlin
fun filterCompatibleCameras(cameraIds: Array<String>, cameraManager: CameraManager): List<String> { return cameraIds.filter { val characteristics = cameraManager.getCameraCharacteristics(it) characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)?.contains( CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) ?: false } } fun filterCameraIdsFacing(cameraIds: List<String>, cameraManager: CameraManager, facing: Int): List<String> { return cameraIds.filter { val characteristics = cameraManager.getCameraCharacteristics(it) characteristics.get(CameraCharacteristics.LENS_FACING) == facing } } fun getNextCameraId(cameraManager: CameraManager, currCameraId: String? = null): String? { // Get all front, back and external cameras in 3 separate lists val cameraIds = filterCompatibleCameras(cameraManager.cameraIdList, cameraManager) val backCameras = filterCameraIdsFacing( cameraIds, cameraManager, CameraMetadata.LENS_FACING_BACK) val frontCameras = filterCameraIdsFacing( cameraIds, cameraManager, CameraMetadata.LENS_FACING_FRONT) val externalCameras = filterCameraIdsFacing( cameraIds, cameraManager, CameraMetadata.LENS_FACING_EXTERNAL) // The recommended order of iteration is: all external, first back, first front val allCameras = (externalCameras + listOf( backCameras.firstOrNull(), frontCameras.firstOrNull())).filterNotNull() // Get the index of the currently selected camera in the list val cameraIndex = allCameras.indexOf(currCameraId) // The selected camera may not be in the list, for example it could be an // external camera that has been removed by the user return if (cameraIndex == -1) { // Return the first camera from the list allCameras.getOrNull(0) } else { // Return the next camera from the list, wrap around if necessary allCameras.getOrNull((cameraIndex + 1) % allCameras.size) } }
জাভা
public List<String> filterCompatibleCameras(CameraManager cameraManager, String[] cameraIds) { final List<String> compatibleCameras = new ArrayList<>(); try { for (String id : cameraIds) { CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(id); int[] capabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES); for (int capability : capabilities) { if (capability == CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) { compatibleCameras.add(id); } } } } catch (CameraAccessException e) { Log.e(TAG, "filterCompatibleCameras: " + e.getMessage()); } return compatibleCameras; } public List<String> filterCameraIdsFacing(CameraManager cameraManager, List<String> cameraIds, int lensFacing) { final List<String> compatibleCameras = new ArrayList<>(); try { for (String id : cameraIds) { CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(id); if (characteristics.get(CameraCharacteristics.LENS_FACING) == lensFacing) { compatibleCameras.add(id); } } } catch (CameraAccessException e) { Log.e(TAG, "filterCameraIdsFacing: " + e.getMessage()); } return compatibleCameras; } public String getNextCameraId(CameraManager cameraManager, @Nullable String currentCameraId) { String nextCameraId = null; try { // Get all front, back, and external cameras in 3 separate lists List<String> compatibleCameraIds = filterCompatibleCameras(cameraManager, cameraManager.getCameraIdList()); List<String> backCameras = filterCameraIdsFacing(cameraManager, compatibleCameraIds, CameraMetadata.LENS_FACING_BACK); List<String> frontCameras = filterCameraIdsFacing(cameraManager, compatibleCameraIds, CameraMetadata.LENS_FACING_FRONT); List<String>externalCameras = filterCameraIdsFacing(cameraManager, compatibleCameraIds, CameraMetadata.LENS_FACING_EXTERNAL); // The recommended order of iteration is: all external, first back, first front List<String> allCameras = new ArrayList<>(externalCameras); if (!backCameras.isEmpty()) allCameras.add(backCameras.get(0)); if (!frontCameras.isEmpty()) allCameras.add(frontCameras.get(0)); // Get the index of the currently selected camera in the list int cameraIndex = allCameras.indexOf(currentCameraId); // The selected camera may not be in the list, for example it could be an // external camera that has been removed by the user if (cameraIndex == -1) { // Return the first camera from the list nextCameraId = !allCameras.isEmpty() ? allCameras.get(0) : null; else { if (!allCameras.isEmpty()) { // Return the next camera from the list, wrap around if necessary nextCameraId = allCameras.get((cameraIndex + 1) % allCameras.size()); } } } catch (CameraAccessException e) { Log.e(TAG, "getNextCameraId: " + e.getMessage()); } return nextCameraId; }
এই কোডটি বিভিন্ন কনফিগারেশন সহ অনেক ডিভাইসের জন্য কাজ করে। এজ কেসের অ্যাকাউন্টিং সম্পর্কে আরও তথ্যের জন্য, CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA দেখুন।
মানানসই অ্যাপ তৈরি করুন
যেসব অ্যাপ এখনও বন্ধ হয়ে যাওয়া ক্যামেরা API ব্যবহার করছে, সেগুলির ক্ষেত্রে
Camera.getNumberOfCameras()
যে ক্যামেরার সংখ্যা দেখায় তা OEM ইমপ্লিমেন্টেশনের উপর নির্ভর করে। সিস্টেমে লজিক্যাল মাল্টি-ক্যামেরা থাকলে, অ্যাপের ব্যাকওয়ার্ড কম্প্যাটিবিলিটি বজায় রাখতে, এই পদ্ধতি প্রতিটি লজিক্যাল ক্যামেরা ও অন্তর্নিহিত ফিজিক্যাল ক্যামেরা গ্রুপের জন্য শুধুমাত্র একটি ক্যামেরা এক্সপোজ করবে।
সব ক্যামেরা দেখতে Camera2 API ব্যবহার করুন।
ক্যামেরা ওরিয়েন্টেশন সম্পর্কে আরও ব্যাকগ্রাউন্ড তথ্যের জন্য, Camera.CameraInfo.orientation দেখুন।
সাধারণত, সব ক্যামেরা
orientation কোয়েরি করতে
Camera.getCameraInfo()
API ব্যবহার করুন
এবং ক্যামেরা পরিবর্তন করছেন এমন ব্যবহারকারীদের জন্য প্রতিটি উপলভ্য ওরিয়েন্টেশনের জন্য শুধুমাত্র একটি ক্যামেরা দেখান।
সব ধরনের ডিভাইসের জন্য উপযুক্ত
আপনার অ্যাপ সবসময় এক বা দুটি ক্যামেরা সহ হ্যান্ডহেল্ড ডিভাইসে চলে বলে ধরে নেবেন না। পরিবর্তে, অ্যাপের জন্য সবচেয়ে উপযুক্ত ক্যামেরা বেছে নিন। আপনার যদি কোনও নির্দিষ্ট ক্যামেরার প্রয়োজন না হয়, তাহলে প্রথম ক্যামেরাটি বেছে নিন যা আপনার কাঙ্ক্ষিত দিকে মুখ করে আছে। নির্দিষ্ট দিকে মুখ করে থাকা ক্যামেরা উপলভ্য না থাকলে, ব্যবহারকারী অন্য কোনও ক্যামেরা ব্যবহার করে তার যাত্রা সম্পূর্ণ করতে পারবেন কিনা তা বিবেচনা করুন। ক্যামেরা হার্ডওয়্যারের উপর ভিত্তি করে নির্দিষ্ট ডিভাইসে আপনার অ্যাপের উপলভ্যতা সীমাবদ্ধ করবেন না। এক্সটার্নাল ক্যামেরা কানেক্ট করা থাকলে, ব্যবহারকারী সম্ভবত এটি ডিফল্ট হিসেবে ব্যবহার করতে পছন্দ করেন।