API ส่วนขยาย Camera2

หมายเหตุ: หน้านี้เกี่ยวข้องกับแพ็กเกจ camera2 เราขอแนะนำให้ใช้ cameraX เว้นแต่ว่าแอปของคุณต้องใช้ฟีเจอร์ระดับต่ำที่เฉพาะเจาะจงจาก Camera2 ทั้ง CameraX และ Camera2 รองรับ Android 5.0 (API ระดับ 21) ขึ้นไป

Camera2 มี Extensions API สำหรับการเข้าถึงส่วนขยายที่ผู้ผลิตอุปกรณ์นำมาใช้งานในอุปกรณ์ Android รุ่นต่างๆ ดูรายการโหมดส่วนขยายที่รองรับได้ที่ส่วนขยายกล้อง

โปรดดูรายการอุปกรณ์ที่รองรับส่วนขยายที่หัวข้ออุปกรณ์ที่รองรับ

สถาปัตยกรรมส่วนขยาย

รูปภาพต่อไปนี้แสดงสถาปัตยกรรมของส่วนขยายกล้อง

วันที่
รูปที่ 1 สถาปัตยกรรมส่วนขยายกล้อง

แอปพลิเคชัน Camera2 สามารถใช้ส่วนขยายผ่าน Camera2 API ได้ กล้อง 2 API แสดงวิธีการค้นหาส่วนขยายที่พร้อมใช้งาน กำหนดค่าส่วนขยาย เซสชันของกล้อง และสื่อสารกับไลบรารี OEM ส่วนขยายกล้อง ช่วงเวลานี้ อนุญาตให้แอปพลิเคชันใช้ส่วนขยาย เช่น กลางคืน, HDR, อัตโนมัติ, โบเก้ หรือ รีทัชใบหน้า

ทดสอบอุปกรณ์กล้องเพื่อดูความเข้ากันได้กับ Camera2 Extensions API

ข้อมูลโค้ดต่อไปนี้จะตรวจสอบว่าอุปกรณ์รองรับ Camera2 หรือไม่ Extensions API อุปกรณ์บางรุ่นไม่รองรับส่วนขยายหรืออุปกรณ์อาจรองรับบางส่วน ส่วนขยาย ข้อมูลโค้ดจะแสดงรายการรหัสกล้องที่เข้ากันได้ซึ่งรองรับ ส่วนขยายกล้อง

KotlinJava

private fun getExtensionCameraIds(cameraManager: CameraManager): List<String> =
   
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        cameraManager
.cameraIdList.filter { cameraId ->
           
val characteristics = cameraManager.getCameraCharacteristics(cameraId)
           
val extensionCharacteristics =
                cameraManager
.getCameraExtensionCharacteristics(cameraId)
           
val capabilities =
                characteristics
.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)
            extensionCharacteristics
.supportedExtensions.isNotEmpty() &&
                    capabilities
?.contains(
                       
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
                   
) ?: false
       
}
   
} else emptyList()


private List<String> getExtensionCameraIds(CameraManager cameraManager)
       
throws CameraAccessException {
   
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
       
return Arrays.stream(cameraManager.getCameraIdList()).filter(cameraId -> {
           
try {
               
CameraCharacteristics characteristics =
                        cameraManager
.getCameraCharacteristics(cameraId);
               
CameraExtensionCharacteristics extensionCharacteristics =
                        cameraManager
.getCameraExtensionCharacteristics(cameraId);
               
IntStream capabilities =
                   
Arrays.stream(
                                characteristics
.get(
                                       
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES
                               
)
                       
);
               
return !extensionCharacteristics.getSupportedExtensions().isEmpty() &&
                       capabilities
.anyMatch(capability -> capability == CameraCharacteristics
                                       
.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
                       
);
           
} catch (CameraAccessException e) {
               
throw new RuntimeException(e);
           
}
       
}).collect(Collectors.toList());
   
} else {
       
return Collections.emptyList();
   
}
}

สร้าง CameraExtensionSession ด้วย Camera2 Extensions API

เมื่อใช้ Camera2 Extensions API เมื่อใช้กับอุปกรณ์ที่เข้ากันได้จะให้คุณเข้าถึง ส่วนขยายกล้องบางรายการ ข้อมูลโค้ดต่อไปนี้แสดงตัวอย่างของ วิธีสร้าง CameraExtensionSession สำหรับการใช้โหมดจับภาพกลางคืนสำหรับแอปพลิเคชัน Camera2 ที่มีอยู่

KotlinJava

private val captureCallbacks = object : CameraExtensionSession.ExtensionCaptureCallback() {
   
// Implement Capture Callbacks
}
private val extensionSessionStateCallback = object : CameraExtensionSession.StateCallback() {
   
override fun onConfigured(session: CameraExtensionSession) {
        cameraExtensionSession
= session
       
try {
           
val captureRequest =
                cameraDevice
.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW).apply {
                    addTarget
(previewSurface)
               
}.build()
            session
.setRepeatingRequest(
                captureRequest
,
               
Dispatchers.IO.asExecutor(),
                captureCallbacks
           
)
       
} catch (e: CameraAccessException) {
           
Snackbar.make(
                previewView
,
               
"Failed to preview capture request",
               
Snackbar.LENGTH_SHORT
           
).show()
            requireActivity
().finish()
       
}
   
}

   
override fun onClosed(session: CameraExtensionSession) {
       
super.onClosed(session)
        cameraDevice
.close()
   
}

   
override fun onConfigureFailed(session: CameraExtensionSession) {
       
Snackbar.make(
            previewView
,
           
"Failed to start camera extension preview",
           
Snackbar.LENGTH_SHORT
       
).show()
        requireActivity
().finish()
   
}
}

private fun startExtensionSession() {
   
val outputConfig = arrayListOf(
       
OutputConfiguration(stillImageReader.surface),
       
OutputConfiguration(previewSurface)
   
)
   
val extensionConfiguration = ExtensionSessionConfiguration(
       
CameraExtensionCharacteristics.EXTENSION_NIGHT,
        outputConfig
,
       
Dispatchers.IO.asExecutor(),
        extensionSessionStateCallback
   
)
    cameraDevice
.createExtensionSession(extensionConfiguration)
}


private CameraExtensionSession.ExtensionCaptureCallback captureCallbacks =
       
new CameraExtensionSession.ExtensionCaptureCallback() {
           
// Implement Capture Callbacks
       
};

private CameraExtensionSession.StateCallback extensionSessionStateCallback =
       
new CameraExtensionSession.StateCallback() {
           
@Override
           
public void onConfigured(@NonNull CameraExtensionSession session) {
                cameraExtensionSession
= session;
               
try {
                   
CaptureRequest.Builder captureRequestBuilder =
                            cameraDevice
.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                    captureRequestBuilder
.addTarget(previewSurface);
                   
CaptureRequest captureRequest = captureRequestBuilder.build();
                    session
.setRepeatingRequest(captureRequest, backgroundExecutor, captureCallbacks);
               
} catch (CameraAccessException e) {
                   
Snackbar.make(
                            previewView
,
                           
"Failed to preview capture request",
                           
Snackbar.LENGTH_SHORT
                   
).show();
                    requireActivity
().finish();
               
}
           
}

           
@Override
           
public void onClosed(@NonNull CameraExtensionSession session) {
               
super.onClosed(session);
                cameraDevice
.close();
           
}

           
@Override
           
public void onConfigureFailed(@NonNull CameraExtensionSession session) {
               
Snackbar.make(
                        previewView
,
                       
"Failed to start camera extension preview",
                       
Snackbar.LENGTH_SHORT
               
).show();
                requireActivity
().finish();
           
}
       
};

private void startExtensionSession() {
   
ArrayList<OutputConfiguration> outputConfig = new ArrayList<>();
    outputConfig
.add(new OutputConfiguration(stillImageReader.getSurface()));
    outputConfig
.add(new OutputConfiguration(previewSurface));
   
ExtensionSessionConfiguration extensionConfiguration = new ExtensionSessionConfiguration(
           
CameraExtensionCharacteristics.EXTENSION_NIGHT,
            outputConfig
,
            backgroundExecutor
,
            extensionSessionStateCallback
   
);
}

แหล่งข้อมูลเพิ่มเติม

สำหรับข้อมูลเพิ่มเติม โปรดดู CameraExtensionCharacteristics และดูตัวอย่าง API ส่วนขยาย Camera2 สาธารณะ สำหรับข้อมูลเพิ่มเติม