এই ডেভেলপার গাইডটি আপনাকে ধাপে ধাপে দেখাবে কীভাবে আপনার অ্যাপকে অ্যান্ড্রয়েড ক্যামেরা২ এপিআই (Android Camera2 API)- এর মাধ্যমে ক্যামেরার একচেটিয়া নিয়ন্ত্রণ এবং এআরকোর (ARCore)-এর সাথে ক্যামেরা অ্যাক্সেস শেয়ার করার মধ্যে নির্বিঘ্নে পরিবর্তন করার সুবিধা দেওয়া যায়।
এই বিষয়টি বোঝার জন্য ধরে নেওয়া হচ্ছে যে আপনার:
ARCore কুইকস্টার্ট সম্পন্ন করা হয়েছে।
অ্যান্ড্রয়েড ক্যামেরা২ এপিআই সম্পর্কে পরিচিতি থাকতে হবে (আরও জানতে অ্যান্ড্রয়েড-নির্দিষ্ট ক্যামেরা২ নমুনাটি পর্যালোচনা করুন)।
নমুনা অ্যাপটি তৈরি করুন এবং চালান
আপনি যখন শেয়ার্ড ক্যামেরা জাভা স্যাম্পল অ্যাপটি বিল্ড এবং রান করেন, তখন এটি একটি ARCore সেশন তৈরি করে যা শেয়ার্ড ক্যামেরা অ্যাক্সেস সমর্থন করে। অ্যাপটি নন-এআর মোডে চালু হয়, যেখানে ARCore পজ করা থাকে।
যখন অ্যাপটি নন-এআর মোডে কাজ করে, তখন ক্যামেরা ভিউয়ারে একটি সেপিয়া রঙের প্রভাব দেখা যায়। এআর মোডে পরিবর্তন করলে, সেপিয়া প্রভাবটি বন্ধ হয়ে যায় এবং অ্যাপটি বিরতি দেওয়া সেশনটি পুনরায় চালু করার মাধ্যমে ক্যামেরার নিয়ন্ত্রণ এআরকোর-এর কাছে ফিরিয়ে দেয়।
আপনি অ্যাপের মধ্যে থাকা এআর সুইচ ব্যবহার করে মোড পরিবর্তন করতে পারেন। প্রিভিউ চলাকালীন, উভয় মোডেই ক্যামেরা২ দ্বারা ধারণ করা ধারাবাহিক ফ্রেমের সংখ্যা প্রদর্শিত হয়।
শেয়ার্ড ক্যামেরা জাভা স্যাম্পল অ্যাপটি বিল্ড ও রান করতে:
অ্যান্ড্রয়েডের জন্য গুগল এআরকোর এসডিকে ডাউনলোড এবং এক্সট্র্যাক্ট করুন।
samples/shared_camera_javaপ্রজেক্টটি খুলুন।নিশ্চিত করুন যে আপনার অ্যান্ড্রয়েড ডিভাইসটি ইউএসবি-র মাধ্যমে ডেভেলপমেন্ট মেশিনের সাথে সংযুক্ত আছে। বিস্তারিত তথ্যের জন্য ARCore সমর্থিত ডিভাইসসমূহ দেখুন।
অ্যান্ড্রয়েড স্টুডিওতে, Run ক্লিক করুন।
.
আপনার ডিভাইসটিকে ডেপ্লয়মেন্ট টার্গেট হিসেবে বেছে নিন এবং আপনার ডিভাইসে স্যাম্পল অ্যাপটি চালু করতে OK ক্লিক করুন।
ডিভাইসে, অ্যাপটিকে ছবি তুলতে ও ভিডিও রেকর্ড করার অনুমতি দিতে চান কিনা তা নিশ্চিত করুন।
নির্দেশিত হলে, ARCore-এর সর্বশেষ সংস্করণটি আপডেট বা ইনস্টল করুন।
নন-এআর এবং এআর মোডের মধ্যে পরিবর্তন করতে AR সুইচটি ব্যবহার করুন।
ARCore-এর মাধ্যমে কোনো অ্যাপকে ক্যামেরা অ্যাক্সেস শেয়ার করার সুবিধা দেওয়ার সংক্ষিপ্ত বিবরণ
আপনার অ্যাপে ARCore ব্যবহার করে শেয়ার্ড ক্যামেরা অ্যাক্সেস চালু করতে এই ধাপগুলো অনুসরণ করুন। সমস্ত কোড স্নিপেট shared_camera_java স্যাম্পলের মধ্যে থাকা SharedCameraActivity.java ফাইলে পাওয়া যাবে।
CAMERA অনুমতির জন্য অনুরোধ করুন
ডিভাইসের ক্যামেরা ব্যবহার করতে হলে, ব্যবহারকারীকে অবশ্যই আপনার অ্যাপকে CAMERA পারমিশন দিতে হবে । ARCore স্যাম্পলগুলোতে একটি CameraPermissionHelper অন্তর্ভুক্ত রয়েছে, যা আপনার অ্যাপের জন্য সঠিক পারমিশন অনুরোধ করার ইউটিলিটি সরবরাহ করে।
জাভা
protected void onResume() {
// Request the camera permission, if necessary.
if (!CameraPermissionHelper.hasCameraPermission(this)) {
CameraPermissionHelper.requestCameraPermission(this);
}
}
কোটলিন
override fun onResume() {
// Request the camera permission, if necessary.
if (!CameraPermissionHelper.hasCameraPermission(this)) {
CameraPermissionHelper.requestCameraPermission(this)
}
}
ARCore ইনস্টল করা এবং হালনাগাদ আছে কিনা তা নিশ্চিত করুন।
ব্যবহার করার আগে ARCore অবশ্যই ইনস্টল এবং হালনাগাদ করা থাকতে হবে। যদি ডিভাইসে ARCore আগে থেকে ইনস্টল করা না থাকে, তাহলে কীভাবে এটি ইনস্টল করার জন্য অনুরোধ করতে হয়, তা নিচের কোড অংশে দেখানো হয়েছে।
জাভা
boolean isARCoreSupportedAndUpToDate() {
// Make sure that ARCore is installed and supported on this device.
ArCoreApk.Availability availability = ArCoreApk.getInstance().checkAvailability(this);
switch (availability) {
case SUPPORTED_INSTALLED:
return true;
case SUPPORTED_APK_TOO_OLD:
case SUPPORTED_NOT_INSTALLED:
// Requests an ARCore installation or updates ARCore if needed.
ArCoreApk.InstallStatus installStatus = ArCoreApk.getInstance().requestInstall(this, userRequestedInstall);
switch (installStatus) {
case INSTALL_REQUESTED:
return false;
case INSTALLED:
return true;
}
return false;
default:
// Handle the error. For example, show the user a snackbar that tells them
// ARCore is not supported on their device.
return false;
}
}
কোটলিন
// Determine ARCore installation status.
// Requests an ARCore installation or updates ARCore if needed.
fun isARCoreSupportedAndUpToDate(): Boolean {
when (ArCoreApk.getInstance().checkAvailability(this)) {
Availability.SUPPORTED_INSTALLED -> return true
Availability.SUPPORTED_APK_TOO_OLD,
Availability.SUPPORTED_NOT_INSTALLED -> {
when(ArCoreApk.getInstance().requestInstall(this, userRequestedInstall)) {
InstallStatus.INSTALLED -> return true
else -> return false
}
}
else -> {
// Handle the error. For example, show the user a snackbar that tells them
// ARCore is not supported on their device.
return false
}
}
}
ক্যামেরা শেয়ারিং সমর্থন করে এমন একটি ARCore সেশন তৈরি করুন।
এর জন্য সেশন তৈরি করতে হয় এবং ARCore শেয়ার্ড ক্যামেরার রেফারেন্স ও আইডি সংরক্ষণ করতে হয়:
জাভা
// Create an ARCore session that supports camera sharing.
sharedSession = new Session(this, EnumSet.of(Session.Feature.SHARED_CAMERA))
// Store the ARCore shared camera reference.
sharedCamera = sharedSession.getSharedCamera();
// Store the ID of the camera that ARCore uses.
cameraId = sharedSession.getCameraConfig().getCameraId();
কোটলিন
// Create an ARCore session that supports camera sharing.
sharedSession = Session(this, EnumSet.of(Session.Feature.SHARED_CAMERA))
// Store the ARCore shared camera reference.
sharedCamera = sharedSession.sharedCamera
// Store the ID of the camera that ARCore uses.
cameraId = sharedSession.cameraConfig.cameraId
(ঐচ্ছিক) যেকোনো কাস্টম সারফেস সম্পর্কে ARCore-কে জানান।
অতিরিক্ত কাস্টম সারফেসের অনুরোধ করলে ডিভাইসের পারফরম্যান্সের চাহিদা বেড়ে যায়। এর পারফরম্যান্স যেন ভালো হয়, তা নিশ্চিত করতে আপনার ব্যবহারকারীরা যে ডিভাইসগুলো ব্যবহার করবেন, সেগুলোতে আপনার অ্যাপটি পরীক্ষা করুন।
ARCore ডিফল্টরূপে দুটি স্ট্রিমের জন্য অনুরোধ করবে:
- ১টি YUV সিপিইউ স্ট্রিম , বর্তমানে সর্বদা
640x480।
ARCore গতি শনাক্তকরণের জন্য এই স্ট্রিমটি ব্যবহার করে। - একটি 1x GPU স্ট্রিম , সাধারণত
1920x1080
বর্তমান GPU স্ট্রিম রেজোলিউশন নির্ধারণ করতেSession#getCameraConfig()ব্যবহার করুন।
সমর্থিত ডিভাইসগুলিতে আপনি getSupportedCameraConfigs() এবং setCameraConfig() ব্যবহার করে GPU স্ট্রিমের রেজোলিউশন পরিবর্তন করতে পারেন।
মোটামুটি ইঙ্গিত হিসেবে, আপনি আশা করতে পারেন:
| ডিভাইসের ধরণ | একই সাথে সমর্থিত স্ট্রিম |
|---|---|
| উচ্চমানের ফোন |
|
| মাঝারি দামের ফোন |
|
কাস্টম সারফেস, যেমন একটি সিপিইউ ইমেজ রিডার সারফেস ব্যবহার করতে, এটিকে আপডেট করার জন্য প্রয়োজনীয় সারফেসের তালিকায় যুক্ত করা নিশ্চিত করুন (উদাহরণস্বরূপ, একটি ImageReader )।
জাভা
sharedCamera.">setAppSurfaces(this.cameraId, Arrays.asList(imageReader.getSurface()));
কোটলিন
sharedCamera.">setAppSurfaces(this.cameraId, listOf(imageReader.surface))
ক্যামেরা খুলুন
ARCore-এ মোড়ানো একটি কলব্যাক ব্যবহার করে ক্যামেরাটি খুলুন:
জাভা
// Wrap the callback in a shared camera callback.
CameraDevice.StateCallback wrappedCallback =
sharedCamera.createARDeviceStateCallback(cameraDeviceCallback, backgroundHandler);
// Store a reference to the camera system service.
cameraManager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);
// Open the camera device using the ARCore wrapped callback.
cameraManager.openCamera(cameraId, wrappedCallback, backgroundHandler);
কোটলিন
// Wrap the callback in a shared camera callback.
val wrappedCallback = sharedCamera.createARDeviceStateCallback(cameraDeviceCallback, backgroundHandler)
// Store a reference to the camera system service.
val cameraManager = this.getSystemService(Context.CAMERA_SERVICE) as CameraManager
// Open the camera device using the ARCore wrapped callback.
cameraManager.openCamera(cameraId, wrappedCallback, backgroundHandler)
ক্যামেরা ডিভাইসের অবস্থা কলব্যাক ব্যবহার করুন
ক্যামেরা ডিভাইস স্টেট কলব্যাকে ক্যামেরা ডিভাইসটির একটি রেফারেন্স সংরক্ষণ করুন এবং একটি নতুন ক্যাপচার সেশন শুরু করুন।
জাভা
public void onOpened(@NonNull CameraDevice cameraDevice) {
Log.d(TAG, "Camera device ID " + cameraDevice.getId() + " opened.");
SharedCameraActivity.this.cameraDevice = cameraDevice;
createCameraPreviewSession();
}
কোটলিন
fun onOpened(cameraDevice: CameraDevice) {
Log.d(TAG, "Camera device ID " + cameraDevice.id + " opened.")
this.cameraDevice = cameraDevice
createCameraPreviewSession()
}
একটি নতুন ক্যাপচার সেশন তৈরি করুন
একটি নতুন ক্যাপচার রিকোয়েস্ট তৈরি করুন। ক্যাপচার রিকোয়েস্টটি যেন ARCore-এর সাথে সামঞ্জস্যপূর্ণ হয় এবং রানটাইমে নন-এআর ও এআর মোডের মধ্যে নির্বিঘ্নে পরিবর্তন করা যায়, তা নিশ্চিত করতে TEMPLATE_RECORD ব্যবহার করুন।
জাভা
void createCameraPreviewSession() {
try {
// Create an ARCore-compatible capture request using `TEMPLATE_RECORD`.
previewCaptureRequestBuilder =
cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
// Build a list of surfaces, starting with ARCore provided surfaces.
List<Surface> surfaceList = sharedCamera.getArCoreSurfaces();
// (Optional) Add a CPU image reader surface.
surfaceList.add(cpuImageReader.getSurface());
// The list should now contain three surfaces:
// 0. sharedCamera.getSurfaceTexture()
// 1. …
// 2. cpuImageReader.getSurface()
// Add ARCore surfaces and CPU image surface targets.
for (Surface surface : surfaceList) {
previewCaptureRequestBuilder.addTarget(surface);
}
// Wrap our callback in a shared camera callback.
CameraCaptureSession.StateCallback wrappedCallback =
sharedCamera.createARSessionStateCallback(cameraSessionStateCallback, backgroundHandler);
// Create a camera capture session for camera preview using an ARCore wrapped callback.
cameraDevice.createCaptureSession(surfaceList, wrappedCallback, backgroundHandler);
} catch (CameraAccessException e) {
Log.e(TAG, "CameraAccessException", e);
}
}
কোটলিন
fun createCameraPreviewSession() {
try {
// Create an ARCore-compatible capture request using `TEMPLATE_RECORD`.
previewCaptureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD)
// Build a list of surfaces, starting with ARCore provided surfaces.
val surfaceList: MutableList<Surface> = sharedCamera.arCoreSurfaces
// (Optional) Add a CPU image reader surface.
surfaceList.add(cpuImageReader.getSurface())
// The list should now contain three surfaces:
// 0. sharedCamera.getSurfaceTexture()
// 1. …
// 2. cpuImageReader.getSurface()
// Add ARCore surfaces and CPU image surface targets.
for (surface in surfaceList) {
previewCaptureRequestBuilder.addTarget(surface)
}
// Wrap the callback in a shared camera callback.
val wrappedCallback = sharedCamera.createARSessionStateCallback(cameraSessionStateCallback, backgroundHandler)
// Create a camera capture session for camera preview using an ARCore wrapped callback.
cameraDevice.createCaptureSession(surfaceList, wrappedCallback, backgroundHandler)
} catch (e: CameraAccessException) {
Log.e(TAG, "CameraAccessException", e)
}
}
নন-এআর বা এআর মোডে শুরু করুন
ফ্রেম ক্যাপচার করা শুরু করতে, ক্যামেরা ক্যাপচার সেশনের onConfigured() স্টেট কলব্যাক থেকে captureSession.setRepeatingRequest() কল করুন। AR মোডে শুরু করার জন্য onActive() কলব্যাকের মধ্যে ARCore সেশনটি পুনরায় চালু করুন।
জাভা
// Repeating camera capture session state callback.
CameraCaptureSession.StateCallback cameraSessionStateCallback =
new CameraCaptureSession.StateCallback() {
// Called when ARCore first configures the camera capture session after
// initializing the app, and again each time the activity resumes.
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
captureSession = session;
setRepeatingCaptureRequest();
}
@Override
public void onActive(@NonNull CameraCaptureSession session) {
if (arMode && !arcoreActive) {
resumeARCore();
}
}
};
// A repeating camera capture session capture callback.
CameraCaptureSession.CaptureCallback cameraCaptureCallback =
new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(…) {
shouldUpdateSurfaceTexture.set(true);
}
};
void setRepeatingCaptureRequest() {
captureSession.setRepeatingRequest(
previewCaptureRequestBuilder.build(), cameraCaptureCallback, backgroundHandler);
}
void resumeARCore() {
// Resume ARCore.
sharedSession.resume();
arcoreActive = true;
// Set the capture session callback while in AR mode.
sharedCamera.setCaptureCallback(cameraCaptureCallback, backgroundHandler);
}
কোটলিন
val cameraSessionStateCallback = object : CameraCaptureSession.StateCallback() {
// Called when ARCore first configures the camera capture session after
// initializing the app, and again each time the activity resumes.
override fun onConfigured(session: CameraCaptureSession) {
captureSession = session
setRepeatingCaptureRequest()
}
override fun onActive(session: CameraCaptureSession) {
if (arMode && !arcoreActive) {
resumeARCore()
}
}
}
val cameraCaptureCallback = object : CameraCaptureSession.CaptureCallback() {
override fun onCaptureCompleted(
session: CameraCaptureSession,
request: CaptureRequest,
result: TotalCaptureResult
) {
shouldUpdateSurfaceTexture.set(true);
}
}
fun setRepeatingCaptureRequest() {
captureSession.setRepeatingRequest(
previewCaptureRequestBuilder.build(), cameraCaptureCallback, backgroundHandler
)
}
fun resumeARCore() {
// Resume ARCore.
sharedSession.resume()
arcoreActive = true
// Set the capture session callback while in AR mode.
sharedCamera.setCaptureCallback(cameraCaptureCallback, backgroundHandler)
}
রানটাইমে নন-এআর বা এআর মোডের মধ্যে নির্বিঘ্নে পরিবর্তন করুন
নন-এআর থেকে এআর মোডে পরিবর্তন করতে এবং একটি বিরতি দেওয়া এআরকোর সেশন পুনরায় চালু করতে:
জাভা
// Resume the ARCore session.
resumeARCore();
কোটলিন
// Resume the ARCore session.
resumeARCore()
AR-মোড থেকে নন-AR মোডে পরিবর্তন করতে:
জাভা
// Pause ARCore.
sharedSession.pause();
// Create the Camera2 repeating capture request.
setRepeatingCaptureRequest();
কোটলিন
// Pause ARCore.
sharedSession.pause()
// Create the Camera2 repeating capture request.
setRepeatingCaptureRequest()
.