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 อุปกรณ์บางรุ่นไม่รองรับส่วนขยายหรืออุปกรณ์อาจรองรับบางส่วน ส่วนขยาย ข้อมูลโค้ดจะแสดงรายการรหัสกล้องที่เข้ากันได้ซึ่งรองรับ ส่วนขยายกล้อง

Kotlin


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()

Java


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 ที่มีอยู่

Kotlin


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)
}

Java


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 สาธารณะ สำหรับข้อมูลเพิ่มเติม