ほねっとのぶろぐ

アニメとAndroidが好きなほねっとのブログです。

Flutterでカメラアプリを作る〜プレビュー表示編〜

f:id:aftercider:20181114175259p:plain

Flutterという、ワンソースでiOSアプリもAndroidアプリもビルドできるGoogle製フレームワークがありまして、そのFlutterを使ってカメラのプレビュー・撮影・保存までのやり方をまとめました。

この記事ではプレビューまでをまとめ、次の記事では撮影・保存をまとめます。

前提

  • Flutter 0.11.3
  • MacBookPro(Mac Mojave)環境
  • Flutterは初めてさわる

インストール

公式ドキュメントにステップバイステップで書いてあるので、これを見ながら導入します。

https://flutter.io/docs/get-started/install

AndroidStudid, XCode, VisualStudioCodeは導入していたので、プラグインだけ設定して完了です。

pubspec.yamlにcameraモジュールを追加

Androidでいうところのapp/buld.gradle、Nodejsでいうところのpackage.jsonにあたるのが、pubspec.yamlです。

YAMLはインデントを使って構造を表現するようになっているので、ぱっと見で大体わかります。

今回はcameraモジュールを追加しましょう。

dependenciesの中にcamera: ^0.2.4を追加します。

name: hello_world_project
description: HelloWorldProject

version: 1.0.0+1

environment:
  sdk: ">=2.0.0-dev.68.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^0.1.2
  english_words: ^3.1.0
  camera: ^0.2.4

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true

AndroidStudioの右上からPackages getを実行して、モジュール群を取得します。AndroidでいうところのSyncですね。

f:id:aftercider:20181114174256p:plain

(Androidのみ)minSDKVersionを21以上にする

cameraモジュールのスペック要件がminSdkVersion:21以上なので、android/app/build.gradleを開き、android -> defaultConfig -> minSdkVersion を21にします。(筆者環境下での初期値は16になってました。)

f:id:aftercider:20181114174255p:plain

カメラのプレビューを表示する

こんな感じで、main.dartを作ります。

import 'dart:async';

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

// カメラ情報のリスト
List<CameraDescription> cameras;

// ここから始まる
Future<Null> main() async {
  cameras = await availableCameras();
  runApp(new CameraApp());
}

// カメラを表示するStatefulWidget
class CameraApp extends StatefulWidget {
  @override
  _CameraAppState createState() => new _CameraAppState();
}

class _CameraAppState extends State<CameraApp> {
  CameraController controller;

  @override
  void initState() {
    super.initState();
    // 背面カメラを高解像度で初期化して表示スタート
    controller = new CameraController(cameras[0], ResolutionPreset.high);
    controller.initialize().then((_) {
      if (!mounted) {
        return;
      }
      setState(() {});
    });
  }

  @override
  void dispose() {
    // 使い終わったらカメラを解放
    controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (!controller.value.isInitialized) {
      return new Container();
    }
    return new AspectRatio(
        aspectRatio: controller.value.aspectRatio,
        child: new CameraPreview(controller));
  }
}

実機で実行

端末をつなぎ、画面上の緑色の実行ボタンをクリックして実行します。

f:id:aftercider:20181114174249p:plain

実行すると、カメラなどのパーミッション要求もきちんとやってくれて、アプリが立ち上がります。

IDE側のLogcatもちゃんと見れるようになっていて、Android開発者にも優しいです。

ちなみにプレビューはこんな感じです。(縦長になってしまうのはカメラの縦横比とライブビューの縦横比が違うため)

f:id:aftercider:20181114174225p:plain

次の記事

次の記事では撮影・保存を行います。