カテゴリー: Tech

Flutterで写真撮影しよう!

はじめに

今回はFlutterでカメラを使用して、プレビューの表示と写真の撮影を行いたいと思います。カメラとかデバイス周りは面倒そうと思っていましたが、かなり簡単に実装できたので紹介します。

準備

まずはパッケージのcameraをpubspec.yamlに追加しましょう。

flutter pub add camera

pubspec.yamlに追加されていれば成功です。

camera: ^0.9.8+1

次は、iOSでカメラを使用するために、Info.plistに以下の内容を追加します。

  <key>NSCameraUsageDescription</key>
    <string>カメラ使います</string>
  <key>NSMicrophoneUsageDescription</key>
    <string>マイクを使います</string>

また、cameraパッケージの動作環境は、iOSでは10以上、Androidは21以上になっています。それ以下のバージョンでは動作しません。

実装

プレビューの表示

最初に、カメラのプレビューをアプリで表示したいと思います。
まずは、デバイスで使用できるカメラの一覧を取得します。

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

late List<CameraDescription> _cameras;

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // 使用できるカメラの一覧取得
  _cameras = await availableCameras();

  runApp(const CameraApp());
}

CameraDescriptionの中身は以下のようになっており、バックカメラやフロントカメラを取得することができます。

CameraDescription(com.apple.avfoundation.avcapturedevice.built-in_video:0, CameraLensDirection.back, 90)

次にカメラを制御するためのCameraControllerを作成します。

class CameraApp extends StatefulWidget {
  /// Default Constructor
  const CameraApp({Key? key}) : super(key: key);

  @override
  State<CameraApp> createState() => _CameraAppState();
}

class _CameraAppState extends State<CameraApp> {
  late CameraController controller;

  @override
  void initState() {
    super.initState();
    controller = CameraController(_cameras[0], ResolutionPreset.max);
    controller.initialize().then((_) {
      if (!mounted) {
        return;
      }
      setState(() {});
    }).catchError((Object e) {
      if (e is CameraException) {
        switch (e.code) {
          case 'CameraAccessDenied':
            print('User denied camera access.');
            break;
          default:
            print('Handle other errors.');
            break;
        }
      }
    });
  }

CameraControllerの第一引数に最初に取得したCameraDescriptionを、第二引数に解像度の指定を入れます。ResolutionPreset.maxを指定することで使用できる最大の解像度を設定してくれます。CameraControllerを生成したらinitializeを行い、CameraControllerの準備は完了です。

@override
Widget build(BuildContext context) {
  if (!controller.value.isInitialized) {
    return Container();
  }
  return MaterialApp(
    home: CameraPreview(controller),
  );
}

最後にCameraPreviewにCameraControllerをセットすれば、カメラのプレビュー表示は完了です。

写真を撮る

プレビューの表示が出来たので、次は写真を取りたいと思います。写真撮影は、CameraControllerのtakePictureを呼び出すことで、簡単に行うことができます。プレビューの表示箇所にFloatingActionButtonを設置してtakePictureを呼びたいと思います。

@override
Widget build(BuildContext context) {
  return MaterialApp(
      home:Scaffold(
        body: Center(
            child: controller.value.isInitialized ?
            CameraPreview(controller) :
            Container()
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () async {
            // 写真を撮る
            final imageFile = await controller.takePicture();
            // path を出力
            print(imageFile.path);
          },
          child: const Icon(Icons.camera_alt),
        ),
      )
  );
}

パスを出力すると以下のようになっているので、jpgで画像が保存されているのがわかります。

flutter: /var/mobile/Containers/Data/Application/xxx/Documents/camera/pictures/CAP_xxx.jpg

 

さいごに

swiftでカメラを使用するときなど、結構面倒なコードを書かなくてはいけないので気後れしていましたが、かなり簡単にプレビュー表示など行えるので気軽に実装できますね。

おすすめ書籍

nukky

シェア
執筆者:
nukky
タグ: Flutter

最近の投稿

フロントエンドで動画デコレーション&レンダリング

はじめに 今回は、以下のように…

3週間 前

Goのクエリビルダー goqu を使ってみる

はじめに 最近携わっているとあ…

1か月 前

【Xcode15】プライバシーマニフェスト対応に備えて

はじめに こんにちは、suzu…

2か月 前

FSMを使った状態管理をGoで実装する

はじめに 一般的なアプリケーシ…

3か月 前