【Flutter】image_pickerを使用してカメラで写真を撮る方法

Twitterや顔診断アプリなどカメラを使うアプリはたくさんあると思います。今回はFlutterでカメラを使う方法を紹介します。

Flutterでカメラを使う方法は2種類あります。1つ目はimage_pickerを使い、アプリからカメラアプリを起動させて使う方法です。2つ目はcameraを使い、アプリ内にカメラを埋め込んで使う方法です。Twitterのプロフィール画像の変更のように、単純に撮影するだけの場合はimage_pickerを使うのが良いです。

今回はimage_pickerを使った簡単なアプリを作りながら、Flutterでカメラを使う方法を説明します。

今回作成するアプリのGIF画像

以下の手順でアプリを作ります。

  1. dependenciesにimage_pickerを追加
  2. Info.plistにkeyを追加
  3. レイアウトを組む
  4. image_pickerで写真を撮る機能を実装
  5. 撮った写真を表示する

1. dependenciesにimage_pickerを追加

image_pickerをインストールするために、pubspec.yamlを開き、dependenciesimage_picker: ^0.6.3+4を追加します。

dependencies:
flutter:
sdk: flutter
image_picker: ^0.6.3+4 # 追加

2. Info.plistにkeyを追加

iOSでカメラアプリを起動させるために、<project root>/ios/Runner/Info.plistNSCameraUsageDescriptionを追加します。

<dict>
<!-- ... 省略 -->
<key>NSCameraUsageDescription</key> <!-- 追加 -->
<string>写真を撮影するためにアクセスします。</string> <!-- 追加 -->
</dict>

<string>写真を撮影するためにアクセスします。</string>の内容はユーザーに許可を求めるときに表示されます。アプリに合わせて適切な内容に書き換えてください。

許可を求めるダイアログのスクリーンショット

3. レイアウトを組む

先にカメラの機能なしで、レイアウトを組みます。main.dartに以下のように記述します。

import 'dart:io';

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Photo app',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Gallery(),
);
}
}

class Gallery extends StatefulWidget {
@override
_GalleryState createState() => _GalleryState();
}

class _GalleryState extends State<Gallery> {

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('ギャラリー'),
),
body: Center(child: Text('写真がありません。')), // 写真を表示する。後で変更します。
floatingActionButton: FloatingActionButton(
onPressed: () => {}, // カメラを起動する。後で実装します。
tooltip: '写真を撮る',
child: const Icon(Icons.camera_alt),
),
);
}
}

Scaffoldbodyに撮った写真を表示し、floatingActionButtonを押すとカメラアプリを起動させるようにします。

4. image_pickerで写真を撮る機能を実装

image_pickerを使用して、写真を撮る機能を実装します。GalleryStateクラス内に以下のような変数と関数を定義します。

class _GalleryState extends State<Gallery> {
// 追加
File _photo;

// 追加
Future<void> takePhoto() async {
File photo = await ImagePicker.pickImage(source: ImageSource.camera);
if (photo == null) return;
setState(() {
_photo = photo;
});
}

/* ... 省略 */
}

File _photoは、GalleryStateクラスに撮った写真を保持しておくための変数です。

ImagePicker.pickImage(source: ImageSource.camera)を実行すると、カメラアプリが起動します。Future<void> takePhoto()では、カメラアプリを起動し、写真を撮った後、setStateを実行して、更新を伝えます。

FloatingActionButtononPressedに、上で定義したtakePhotoを渡します。

FloatingActionButton(
onPressed: takePhoto, // 書き換え
tooltip: '写真を撮る',
child: const Icon(Icons.camera_alt),
),

5. 撮った写真を表示する

Scaffoldbodyを以下のように書き換えます。

Scaffold(
appBar: AppBar(
title: const Text('ギャラリー'),
),
// 書き換え
body: _photo == null
? Center(child: Text('写真がありません。'))
: Center(child: Image.file(_photo)),
floatingActionButton: FloatingActionButton(
onPressed: takePhoto,
tooltip: '写真を撮る',
child: const Icon(Icons.camera_alt),
),
);

写真を一枚も撮っていない時は、Text('写真がありません。')を表示し、写真を撮った後は、Image.file(_photo)を表示します。

コードの全体

コードの全体は以下のようになります。

import 'dart:io';

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Photo app',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Gallery(),
);
}
}

class Gallery extends StatefulWidget {
@override
_GalleryState createState() => _GalleryState();
}

class _GalleryState extends State<Gallery> {
File _photo;

Future<void> takePhoto() async {
File photo = await ImagePicker.pickImage(source: ImageSource.camera);
if (photo == null) return;
setState(() {
_photo = photo;
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('ギャラリー'),
),
body: _photo == null
? Center(child: Text('写真がありません。'))
: Center(child: Image.file(_photo)),
floatingActionButton: FloatingActionButton(
onPressed: takePhoto,
tooltip: '写真を撮る',
child: const Icon(Icons.camera_alt),
),
);
}
}

最後に

今回はimage_pickerを使用してカメラで写真を撮る方法を、簡単なアプリを作りながら説明しました。

この記事に対して以下からリアクションして頂けると嬉しいです。また、間違いや分からない事があれば是非コメントして下さい。

シェア