[Flutter] Cameraプラグインを使って写真を撮影する方法

[Flutter] Cameraプラグインを使って写真を撮影する方法

2023-07-15 hit count image

Flutterで写真撮影などカメラの機能を使うためCameraプラグインを使う方法について説明します。

概要

Flutterで写真撮影などカメラの機能を使うためにはFlutterが適用するCameraプラグインを使う必要があります。

今回のブログポストではCameraプラグインを使って写真撮影をする方法について説明します。ここで紹介するソースコードはGitHubで確認できます。

プロジェクト生成

Cameraプラグインを使ってFlutterで写真撮影をする方法を確認するため、次のコマンドを使って新しいFlutterプロジェクトを生成します。

flutter create camera_example

Cameraプラグインのインストール

新しいFlutterプロジェクトが生成されたら、次のコマンドを使ってCameraプラグインをインストールします。

flutter pub add camera

iOSの設定

iOSCameraプラグインを使うためには権限の設定をする必要があります。ios/Runner/Info.plistファイルを開いて下記のように権限を追加します。

  ...
	<key>NSCameraUsageDescription</key>
	<string>Camera permission is required.</string>
	<key>NSMicrophoneUsageDescription</key>
	<string>Microphone permission is required.</string>
</dict>
</plist>

アンドロイドの設定

CameraプラグインはアンドロイドSDK21以上のみをサポートします。従ってandroid/app/build.gradleファイルを開いて次のようにminSdkVersionを修正する必要があります。

  ...
  defaultConfig {
    ...
    minSdkVersion 21
    ...
  }
  ...

写真撮影実装

今回のブログポストではCameraプラグインを使って写真を撮影する画面と撮影した写真を見せる画面を実装する方法について紹介します。

写真撮影

Cameraプラグインを使って写真撮影する画面を実装するためには、lib/camera_screen.dartファイルを生成して次のように修正します。

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

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

  @override
  State<CameraScreen> createState() => _CameraScreenState();
}

class _CameraScreenState extends State<CameraScreen> {
  CameraController? _cameraController;
  bool _isCameraReady = false;

  @override
  void initState() {
    super.initState();

    availableCameras().then((cameras) {
      if (cameras.isNotEmpty && _cameraController == null) {
        _cameraController = CameraController(
          cameras.first,
          ResolutionPreset.medium,
        );

        _cameraController!.initialize().then((_) {
          setState(() {
            _isCameraReady = true;
          });
        });
      }
    });
  }

  void _onTakePicture(BuildContext context) {
    _cameraController!.takePicture().then((image) {
      Navigator.of(context).push(
        MaterialPageRoute(
          builder: (context) => PhotoPreview(
            imagePath: image.path,
          ),
        ),
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Take a photo')),
      body: SafeArea(
        child: Column(
          children: [
            Expanded(
              flex: 1,
              child: _cameraController != null && _isCameraReady
                  ? CameraPreview(_cameraController!)
                  : Container(
                      color: Colors.grey,
                    ),
            ),
            Padding(
              padding: const EdgeInsets.all(16),
              child: ElevatedButton(
                onPressed: _cameraController != null
                    ? () => _onTakePicture(context)
                    : null,
                child: const Text('Take a photo'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Cameraプラグインを使うコードをもう少し詳しく見てみましょう。

...
@override
void initState() {
  super.initState();

  availableCameras().then((cameras) {
    if (cameras.isNotEmpty && _cameraController == null) {
      _cameraController = CameraController(
        cameras.first,
        ResolutionPreset.medium,
      );

      _cameraController!.initialize().then((_) {
        setState(() {
          _isCameraReady = true;
        });
      });
    }
  });
}
...

CameraプラグインのavailableCameras関数を使ってカメラが使用可能か確認します。カメラが使用可能ならCameraControllerを初期化します。

...
Expanded(
  flex: 1,
  child: _cameraController != null && _isCameraReady
      ? CameraPreview(_cameraController!)
      : Container(
          color: Colors.grey,
        ),
),
...

このように初期化したCameraControllerCameraプラグインが提供するCameraPreviewウィジェットを使ってカメラ撮影画面を構成します。

...
void _onTakePicture(BuildContext context) {
  _cameraController!.takePicture().then((image) {
    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) => PhotoPreview(
          imagePath: image.path,
        ),
      ),
    );
  });
}
...

最後にCameraControllertakePicture関数を使って写真を撮影する機能を実装しまs。写真撮影が完了すると、XFileという結果が返されます。このように返された写真のイメージパスを写真撮影結果を表示するための画面に渡します。

写真撮影結果表示

Cameraプラグインを使って撮影した写真を画面に表示するため、lib/photo_preview.dartファイルを生成して次のように修正します。

import 'dart:io';

import 'package:flutter/material.dart';

class PhotoPreview extends StatelessWidget {
  final String imagePath;

  const PhotoPreview({required this.imagePath, super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Preview')),
      body: Container(
        color: Colors.grey,
        child: Center(
          child: Image.file(
            File(imagePath),
          ),
        ),
      ),
    );
  }
}

Cameraプラグインで撮影した写真のパスを渡してもらったので、渡してもらった写真のパスをImage.fileを使って表示します。

...
child: Image.file(
  File(imagePath),
),
...

main.dart

このように作った画面を使うためlib/main.dartファイルを次のように修正します。

import 'package:camera_example/camera_screen.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Camera Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const CameraScreen(),
    );
  }
}

確認

FlutterCameraプラグインを使って写真撮影機能を実装してみました。次はアプリを実行して写真撮影機能がうまく動作するか確認してみます。

カメラ機能はシミュレータ(エミューレータ)では使うことができないので、実際の端末を使ってアプリを実行する必要があります。アプリを実行すると次のようにカメラの権限を聞いてくる画面が表示されます。

Flutter Camera plugin - camera permission on iOS

OKを押して権限を設定したら、次のようにマイクに関する権限を聞く画面が表示されます。

Flutter Camera plugin - microphone permission on iOS

全ての権限を設定したら次のようにカメラ撮影画面が表示されることが確認できます。

Flutter Camera plugin - take a photo view on iOS

最後はTake a photoボタンを押して写真を撮影したら次のように撮影された写真が画面に表示されることが確認できます。

Flutter Camera plugin - image preview on iOS

テストコード

Cameraプラグインを使って実装した写真撮影機能に関するテストコードは次のブログポストを参考してください。

完了

これでCameraプラグインを使ってFlutterで写真撮影機能を実装する方法についてみてみました。公式ドキュメントでもCameraプラグインを使って写真撮影機能を実装する方法について紹介しているので、参考にしてみてください。

私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!

アプリ広報

今見てるブログを作成たDekuが開発したアプリを使ってみてください。
Dekuが開発したアプリはFlutterで開発されています。

興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。

Posts