flutter로 내장된 카메라 사용하기

오늘은 flutter로 앱이 실행되고 있는 기기의 카메라를 사용해보려 합니다.

에뮬레이터 및 기기 준비하기

안드로이드나 ios 앱으로 테스트할 장치를 준비해야 합니다.

준비했으면, 미리 기기 또는 에뮬레이터를 ide에 연결해줍니다.

pubspec.yaml 작성하기

dependencies:
  flutter:
    sdk: flutter
  camera:

flutter에서 카메라를 사용하려면 camera 패키지를 pubspec.yaml에 작성해줍니다.

android

안드로이드에서 해당 패키지를 사용하려면 build.gradle 파일을 열고 약간의 작업이 필요합니다.

defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.example.flutter_camera_test"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

minSdkVersion가 기본적으로 16이라고 적혀있지만, 21로 설정해야 합니다.

ios

ios/Runner/Info.plist 파일에서 카메라와 마이크로 폰의 키를 설정해야 합니다.

main.dart 앱 코드 작성하기

import 'package:flutter/material.dart';
import 'package:camera/camera.dart';

앱에 머티리얼 위젯을 추가할 수 있는 material 패키지와 카메라를 사용할 수 있는 camera 패키지를 가져옵니다.

List<CameraDescription> cameras;

cameras의 목록을 만들 수 있는 변수를 선언합니다.

void main() async {
  cameras = await availableCameras();
  runApp(MyApp());
}

사용 가능한 카메라 목록에 추가하고 앱을 MyApp으로 구동합니다.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(),
    );
  }
}

머티리얼 디자인으로 감싸진 MyHomePage 객체를 화면에 그려줍니다.

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

StatefulWidget으로 버튼, 슬라이더, 체크 박스처럼 사용자와 상호작용하여 위젯이 변화하는 것을 묶어줍니다.

createState 메소드를 오버라이딩하여 _MyHomePageState 객체를 생성해줍니다.

class _MyHomePageState extends State<MyHomePage> {
  CameraController controller;

카메라를 제어할 수 있는 카메라 컨트롤러를 추가합니다.

  @override
  void initState() {
    super.initState();
    controller = CameraController(cameras[0], ResolutionPreset.high);
    controller.initialize().then((_) {
      if (!mounted) {
        return;
      }
      setState(() {});
    });
  }

initState를 오버라이딩하여 카메라 목록의 첫번째 카메라를 CameraController에 추가하고, 초기화합니다.

초기화할 때에는 setState에 의해 화면을 그리게 됩니다.

  @override
  void dispose() {
    controller?.dispose();
    super.dispose();
  }

앱이 dispose될 때에는 컨트롤러도 처리합니다.

  @override
  Widget build(BuildContext context) {
    if (!controller.value.isInitialized) {
      return Container();
    }

만약 컨트롤러가 초기화되지 않았다면, Container만 화면을 그려줍니다.

    return Scaffold(
        body: AspectRatio(
            aspectRatio: controller.value.aspectRatio,
            child: CameraPreview(controller)),
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.camera),
          onPressed: () async {
            // controller.takePicture(path)
          },
        ));
  }
}

만약 컨트롤러가 초기화되있다면, 카메라의 화면을 보여주는 CameraPreview를 가로세로비를 관리하는 AspectRatio의 안에 넣어줍니다.

주석에 적힌대로 controller로 다양한 행동을 할 수 있습니다.

Written on March 3, 2019