Camera(FlashMode)

샤워실의 바보·2024년 2월 15일
0
post-thumbnail
post-custom-banner
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:tiktok_clone/constants/gaps.dart';
import 'package:tiktok_clone/constants/sizes.dart';

class VideoRecordingScreen extends StatefulWidget {
  const VideoRecordingScreen({super.key});

  
  State<VideoRecordingScreen> createState() => _VideoRecordingScreenState();
}

class _VideoRecordingScreenState extends State<VideoRecordingScreen> {
  bool _hasPermission = false; // 카메라 및 마이크 접근 권한의 상태를 저장합니다.
  bool _isSelfieMode = false; // 현재 카메라가 셀피 모드인지 아닌지를 나타냅니다.

  late FlashMode _flashMode; // 현재 설정된 플래시 모드를 저장합니다.
  late CameraController _cameraController; // 카메라의 상태와 제어를 담당합니다.

  // 카메라를 초기화하는 함수입니다.
  Future<void> initCamera() async {
    final cameras = await availableCameras();

    if (cameras.isEmpty) {
      return;
    }

    _cameraController = CameraController(
      cameras[_isSelfieMode ? 1 : 0], // 셀피 모드 여부에 따라 카메라를 선택합니다.
      ResolutionPreset.ultraHigh, // 최대 해상도로 설정합니다.
    );

    await _cameraController.initialize();
    _flashMode = _cameraController.value.flashMode; // 현재 플래시 모드를 초기화합니다.
  }

  // 카메라 및 마이크 접근 권한을 요청하는 함수입니다.
  Future<void> initPermissions() async {
    final cameraPermission = await Permission.camera.request();
    final micPermission = await Permission.microphone.request();

    // 접근이 거부되었는지 확인합니다.
    final cameraDenied = cameraPermission.isDenied || cameraPermission.isPermanentlyDenied;
    final micDenied = micPermission.isDenied || micPermission.isPermanentlyDenied;

    if (!cameraDenied && !micDenied) {
      _hasPermission = true;
      await initCamera(); // 권한이 승인되면 카메라를 초기화합니다.
      setState(() {});
    }
  }

  
  void initState() {
    super.initState();
    initPermissions();
  }

  // 셀피 모드를 전환하는 함수입니다.
  Future<void> _toggleSelfieMode() async {
    _isSelfieMode = !_isSelfieMode;
    await initCamera();
    setState(() {});
  }

  // 플래시 모드를 설정하는 함수입니다.
  Future<void> _setFlashMode(FlashMode newFlashMode) async {
    await _cameraController.setFlashMode(newFlashMode); // 새로운 플래시 모드로 설정합니다.
    _flashMode = newFlashMode; // 상태를 업데이트합니다.
    setState(() {});
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: SizedBox(
        width: MediaQuery.of(context).size.width,
        child: !_hasPermission || !_cameraController.value.isInitialized
            ? Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisAlignment: MainAxisAlignment.center,
                children: const [
                  Text("Initializing...", style: TextStyle(color: Colors.white, fontSize: Sizes.size20)),
                  Gaps.v20,
                  CircularProgressIndicator.adaptive()
                ],
              )
            : Stack(
                alignment: Alignment.center,
                children: [
                  CameraPreview(_cameraController), // 카메라 미리보기를 표시합니다.
                  Positioned( // 플래시 모드 조절 버튼을 배치합니다.
                    top: Sizes.size20,
                    right: Sizes.size20,
                    child: Column(
                      children: [
                        IconButton(
                          color: Colors.white,
                          onPressed: _toggleSelfieMode, // 셀피 모드 전환 버튼
                          icon: const Icon(Icons.cameraswitch),
                        ),
                        Gaps.v10,
                        // 플래시 모드 설정 버튼들입니다. 현재 플래시 모드에 따라 아이콘 색상이 변경됩니다.
                        IconButton(
                          color: _flashMode == FlashMode.off ? Colors.amber.shade200 : Colors.white,
                          onPressed: () => _setFlashMode(FlashMode.off),
                          icon: const Icon(Icons.flash_off_rounded),
                        ),
                        Gaps.v10,
                        IconButton(
                          color: _flashMode == FlashMode.always ? Colors.amber.shade200 : Colors.white,
                          onPressed: () => _setFlashMode(FlashMode.always),
                          icon: const Icon(Icons.flash_on_rounded),
                        ),
                        // 이하 동일한 패턴으로 플래시 모드를 설정하는 버튼들이 계속됩니다.
                      ],
                    ),
                  ),
                ],
              ),
      ),
    );
  }
}

이 코드에서 플래시 모드와 관련된 로직은 사용자가 카메라 앱 내에서 플래시의 작동 방식을 조절할 수 있게 해줍니다. 이는 특히 다양한 조명 조건에서 비디오 또는 사진을 촬영할 때 유용합니다. 여기서 사용된 주요 기능과 절차를 요약하면 다음과 같습니다:

  1. 카메라 컨트롤러 초기화: _cameraControllerCameraController 객체를 사용해 초기화되며, 이는 선택된 카메라와 해상도 프리셋(ResolutionPreset.ultraHigh)을 설정합니다. 이 과정에서 _flashMode도 현재 카메라 컨트롤러의 플래시 모드 값으로 초기화됩니다.

  2. 권한 요청: initPermissions 함수는 카메라와 마이크 사용에 필요한 사용자 권한을 요청합니다. 모든 권한이 승인되면 카메라가 초기화됩니다.

  3. 셀피 모드 전환: _toggleSelfieMode 함수는 _isSelfieMode의 값을 토글하여 셀피 모드를 전환하고, 카메라를 재초기화합니다. 이는 사용자가 전면 카메라와 후면 카메라를 전환할 수 있게 합니다.

  4. 플래시 모드 설정: _setFlashMode 함수는 새로운 플래시 모드(FlashMode)를 인자로 받아 _cameraController를 통해 해당 모드로 설정합니다. 이 설정은 비디오 또는 사진 촬영 시 플래시의 동작 방식을 결정합니다.

  5. UI 상호작용: 사용자는 UI 상의 아이콘 버튼을 통해 플래시 모드를 FlashMode.off, FlashMode.always, FlashMode.auto, FlashMode.torch 중에서 선택할 수 있습니다. 각 버튼은 해당 플래시 모드로 설정하는 기능을 수행하며, 선택된 플래시 모드에 따라 아이콘의 색상이 변경되어 현재 설정을 시각적으로 표시합니다.

이 로직을 통해 사용자는 앱 내에서 플래시 모드를 동적으로 조절할 수 있으며, 이는 어두운 환경에서의 촬영이나 특정 효과를 주기 위한 촬영에서 유용하게 사용될 수 있습니다.

profile
공부하는 개발자
post-custom-banner

0개의 댓글