Files
photobooth-app/3_ANDROID_CAMERA.md
T

5.2 KiB

📸 KẾ HOẠCH PHÁT TRIỂN: TÍNH NĂNG CAMERA NÂNG CAO (ANDROID)

Mục tiêu: Hoàn thiện bộ điều khiển Camera đầy đủ cho ứng dụng Photobooth bao gồm: Đổi camera, Hẹn giờ (Timer), Điều khiển Flash, và Chuyển đổi các ống kính Zoom định sẵn (0.5x, 1x, 3x).


🛠️ 1. Cấu Trúc File Cập Nhật Quy Trình UI (activity_main.xml)

Chúng ta cần bổ sung các nút bấm vào giao diện để người dùng tương tác. Cập nhật file res/layout/activity_main.xml với các ID trực quan.

<!-- Thêm các nút điều khiển vào phía trên kính ngắm (Top Bar) -->
<!-- 1. Nút Đổi Camera: id=@+id/btnSwitchCamera -->
<!-- 2. Nút Flash (On/Off/Auto): id=@+id/btnFlash -->
<!-- 3. Nút Hẹn giờ (Off/3s/5s/10s): id=@+id/btnTimer -->

<!-- Thêm thanh chọn Zoom vào ngay trên Control Panel -->
<!-- Gồm 3 nút tương ứng: 0.5x, 1x, 3x -->
<!-- id=@+id/btnZoom05, id=@+id/btnZoom10, id=@+id/btnZoom30 -->


💻 2. Kế Hoạch Hiện Thực Hóa Logic (Kotlin trong MainActivity.kt)

Dưới đây là kiến trúc mã nguồn và các biến trạng thái cần quản lý để thực hiện các tính năng.

🔹 2.1. Khai báo các biến trạng thái (State Management)

Đặt các biến này ở đầu class MainActivity để theo dõi cấu hình hiện tại:

private var lensFacing = CameraSelector.DEFAULT_FRONT_CAMERA // Mặc định camera trước
private var flashMode = ImageCapture.FLASH_MODE_OFF          // Mặc định tắt flash
private var timerSeconds = 0                                 // Mặc định không hẹn giờ (0s)
private var cameraControl: CameraControl? = null             // Dùng để điều khiển Zoom/Flash
private var cameraInfo: CameraInfo? = null                   // Dùng để đọc thông số phần cứng

🔹 2.2. Logic Tính Năng Chi Tiết & Giải Pháp Code

  1. Chuyển Đổi Camera (Trước ⇄ Sau): Xử lý lật ống kính. Khi bấm btnSwitchCamera, đổi giá trị lensFacing giữa CameraSelector.DEFAULT_FRONT_CAMERADEFAULT_BACK_CAMERA. Sau đó gọi lại hàm startCamera() để giải phóng session cũ và bind session mới.

  2. Điều Khiển Đèn Flash: On / Off / Auto. Khi khởi tạo ImageCapture, gán trực tiếp thuộc tính: imageCapture.flashMode = flashMode. Khi người dùng bấm nút Flash, thay đổi biến trạng thái và cập nhật icon tương ứng (, , Ⓐ).

  3. Cơ Chế Hẹn Giờ Chụp (Timer): Đếm ngược trực quan. Sử dụng CountDownTimer của Android. Khi bấm nút chụp: Nếu timerSeconds > 0, hiển thị một TextView số lớn ở giữa màn hình, đếm ngược mỗi giây và phát âm thanh "Tích". Khi đếm về 0, kích hoạt hàm takePicture().

  4. Hệ Thống Zoom Cố Định (0.5x, 1x, 3x): Điều khiển Zoom kỹ thuật số/quang học. Sau khi bindToLifecycle, lấy đối tượng camera.cameraControl. Sử dụng lệnh: cameraControl?.setZoomRatio(ratio) khi người dùng bấm vào các nút zoom:

  • 0.5x: setZoomRatio(0.5f) (Lưu ý: Thiết bị phải có camera góc siêu rộng phần cứng mới hoạt động thực tế, nếu không CameraX tự thu phóng số).
  • 1x: setZoomRatio(1.0f)
  • 3x: setZoomRatio(3.0f)

📝 3. Đoạn Code Mẫu Triển Khai Bộ Thu Phóng (Zoom) và Lật Camera

Bạn có thể dán đoạn logic này vào MainActivity.kt sau khi hoàn thiện phần giao diện:

// Hàm xử lý đổi Camera
private fun toggleCamera() {
    lensFacing = if (lensFacing == CameraSelector.DEFAULT_FRONT_CAMERA) {
        CameraSelector.DEFAULT_BACK_CAMERA
    } else {
        CameraSelector.DEFAULT_FRONT_CAMERA
    }
    startCamera() // Khởi động lại camera với ống kính mới
}

// Hàm xử lý Zoom mượt mà bằng CameraControl
private fun applyZoom(ratio: Float) {
    cameraInfo?.zoomState?.value?.let { currentState ->
        val maxZoom = currentState.maxZoomRatio
        val minZoom = currentState.minZoomRatio
        
        // Kiểm tra xem thiết bị có hỗ trợ mức zoom này không
        if (ratio in minZoom..maxZoom) {
            cameraControl?.setZoomRatio(ratio)
        } else {
            Toast.makeText(this, "Thiết bị không hỗ trợ mức zoom ${ratio}x", Toast.LENGTH_SHORT).show()
        }
    }
}


📅 4. Các Đầu Việc Cần Hoàn Thành (Checklist)

  • Thiết kế các Icon cho nút bấm (Đổi camera, Flash, Hẹn giờ) và đưa vào thư mục res/drawable.
  • Cập nhật giao diện activity_main.xml xếp chồng các nút điều khiển lên trên kính ngắm.
  • Viết hàm setupCameraControls() để gán sự kiện setOnClickListener cho tất cả các nút bấm.
  • Khởi tạo thêm ImageCapture bên cạnh Preview để sẵn sàng cho việc nhận lệnh chụp ảnh từ bộ hẹn giờ.
  • Kiểm thử tính năng Zoom và lật Camera trên thiết bị thật (Khuyên dùng thiết bị thật vì Emulator không mô phỏng được camera góc rộng 0.5x hoặc tele 3x).