Bu geliştirici kılavuzu, uygulamanızın Android Camera2 API aracılığıyla kameranın özel kontrolü ile ARCore ile kamera erişimini paylaşma arasında sorunsuz bir şekilde geçiş yapmasını sağlama adımlarında size yol gösterir.
Bu konuda şunları yaptığınız varsayılmaktadır:
ARCore Hızlı Başlangıç'ı tamamlamış olmanız gerekir.
Android Camera2 API hakkında bilgi sahibi olmanız gerekir. (Daha fazla bilgi edinmek için Android'e özgü Camera2 örneğini inceleyin.)
Örnek uygulamayı derleyip çalıştırma
Shared Camera Java örnek uygulamasını oluşturup çalıştırdığınızda, paylaşılan kamera erişimini destekleyen bir ARCore oturumu oluşturulur. Uygulama, ARCore duraklatılmış şekilde AR dışı modda başlar.
Uygulama AR dışı modda çalışırken kamera görüntüleyicide sepya renk efekti gösterilir. AR moduna geçildiğinde, uygulama duraklatılmış oturumu devam ettirerek kamera kontrolünü ARCore'a geri verdiğinden sepya efekti devre dışı kalır.
Modları değiştirmek için uygulamadaki AR anahtarını kullanabilirsiniz. Önizleme sırasında her iki modda da Camera2 tarafından çekilen sürekli kare sayısı gösterilir.
Paylaşılan Kamera Java örnek uygulamasını oluşturmak ve çalıştırmak için:
Android için Google ARCore SDK'sını indirip ayıklayın.
samples/shared_camera_javaprojesini açın.Android cihazınızın USB üzerinden geliştirme makinesine bağlı olduğundan emin olun. Ayrıntılı bilgi için ARCore Desteklenen cihazlar sayfasına bakın.
Android Studio'da Run
simgesini tıklayın.
Dağıtım hedefi olarak cihazınızı seçin ve OK simgesini tıklayarak örnek uygulamayı cihazınızda başlatın.
Cihazda, uygulamanın fotoğraf çekmesine ve video kaydetmesine izin vermek istediğinizi onaylayın.
İstenirse ARCore'un en son sürümünü güncelleyin veya yükleyin.
Artırılmış gerçeklik (AR) modu ile AR olmayan mod arasında geçiş yapmak için AR anahtarını kullanın.
Bir uygulamanın ARCore ile kamera erişimini paylaşmasını etkinleştirmeye genel bakış
Uygulamanızda ARCore ile paylaşılan kamera erişimini uygulamak için aşağıdaki adımları uygulayın.
Tüm kod snippet'leri, SharedCameraActivity.java
shared_camera_java
örneğinde mevcuttur.
CAMERA izni iste
Kullanıcının cihazın kamerasını kullanabilmesi için uygulamanıza CAMERA iznini vermesi gerekir.
ARCore örneklerinde, uygulamanız için doğru izni istemek üzere yardımcı programlar sağlayan bir CameraPermissionHelper bulunur.
Java
protected void onResume() {
// Request the camera permission, if necessary.
if (!CameraPermissionHelper.hasCameraPermission(this)) {
CameraPermissionHelper.requestCameraPermission(this);
}
}
Kotlin
override fun onResume() {
// Request the camera permission, if necessary.
if (!CameraPermissionHelper.hasCameraPermission(this)) {
CameraPermissionHelper.requestCameraPermission(this)
}
}
ARCore'un yüklü ve güncel olduğundan emin olun.
ARCore'un kullanılabilmesi için yüklenmesi ve güncel olması gerekir. Aşağıdaki snippet'te, ARCore cihaza henüz yüklenmemişse nasıl yükleneceği gösterilmektedir.
Java
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;
}
}
Kotlin
// 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
}
}
}
Kamera paylaşımını destekleyen bir ARCore oturumu oluşturma
Bu işlem, oturumu oluşturmayı ve ARCore paylaşılan kameranın referansını ve kimliğini depolamayı içerir:
Java
// 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();
Kotlin
// 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
(İsteğe bağlı) ARCore'a özel yüzeyler hakkında bilgi verme
Ek özel yüzeyler istemek cihazın performans taleplerini artırır. Uygulamanızın iyi performans gösterdiğinden emin olmak için kullanıcılarınızın kullanacağı cihazlarda test edin.
ARCore, varsayılan olarak iki akış ister:
- 1x YUV CPU akışı, şu anda her zaman
640x480.
ARCore, bu akışı hareket izleme için kullanır. - Genellikle
1920x1080
olan bir 1x GPU akışı Mevcut GPU akışının çözünürlüğünü belirlemek içinSession#getCameraConfig()simgesini kullanın.
Desteklenen cihazlarda GPU akışının çözünürlüğünü değiştirmek için
getSupportedCameraConfigs()
ve
setCameraConfig() simgelerini kullanabilirsiniz.
Kabaca bir gösterge olarak şunları bekleyebilirsiniz:
| Cihazın türü | Desteklenen eşzamanlı yayın sayısı |
|---|---|
| Üst düzey telefonlar |
|
| Orta segment telefonlar |
|
CPU görüntü okuyucu yüzeyi gibi özel yüzeyleri kullanmak için bu yüzeyleri güncellenmesi gereken yüzeyler listesine eklediğinizden emin olun (örneğin, ImageReader).
Java
sharedCamera.">setAppSurfaces(this.cameraId, Arrays.asList(imageReader.getSurface()));
Kotlin
sharedCamera.">setAppSurfaces(this.cameraId, listOf(imageReader.surface))
Kamerayı açma
ARCore sarmalı geri çağırma işlevini kullanarak kamerayı açın:
Java
// 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);
Kotlin
// 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)
Kamera cihazı durumu geri çağırmasını kullanma
Kamera cihazı durum geri çağırma işlevinde kamera cihazına bir referans depolayın ve yeni bir yakalama oturumu başlatın.
Java
public void onOpened(@NonNull CameraDevice cameraDevice) {
Log.d(TAG, "Camera device ID " + cameraDevice.getId() + " opened.");
SharedCameraActivity.this.cameraDevice = cameraDevice;
createCameraPreviewSession();
}
Kotlin
fun onOpened(cameraDevice: CameraDevice) {
Log.d(TAG, "Camera device ID " + cameraDevice.id + " opened.")
this.cameraDevice = cameraDevice
createCameraPreviewSession()
}
Yeni bir yakalama oturumu oluşturma
Yeni bir yakalama isteği oluşturun. Yakalama isteğinin ARCore ile uyumlu olduğundan emin olmak ve çalışma zamanında AR olmayan mod ile AR modu arasında sorunsuz geçişe izin vermek için TEMPLATE_RECORD kullanın.
Java
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);
}
}
Kotlin
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)
}
}
AR dışı veya AR modunda başlatma
Kare yakalamaya başlamak için kamera yakalama oturumundan captureSession.setRepeatingRequest()
onConfigured() durum geri çağırmasını çağırın.
AR modunda başlatmak için onActive() geri çağırma işlevi içinde ARCore oturumuna devam edin.
Java
// 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);
}
Kotlin
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)
}
Çalışma zamanında AR olmayan veya AR modları arasında sorunsuz geçiş yapma
AR olmayan moddan AR moduna geçmek ve duraklatılmış bir ARCore oturumunu devam ettirmek için:
Java
// Resume the ARCore session.
resumeARCore();
Kotlin
// Resume the ARCore session.
resumeARCore()
AR modundan AR olmayan moda geçmek için:
Java
// Pause ARCore.
sharedSession.pause();
// Create the Camera2 repeating capture request.
setRepeatingCaptureRequest();
Kotlin
// Pause ARCore.
sharedSession.pause()
// Create the Camera2 repeating capture request.
setRepeatingCaptureRequest()
simgesini tıklayın.