Flutterではカメラ&ギャラリーから3行で画像が取得&表示できて感動した!!

---
# :book: Flutterの記事を整理し本にしました :book:
https://zenn.dev/kazutxt/books/flutter_practice_introduction

* <font color="red"><b>本稿の記事を含む様々な記事を体系的に整理し本にまとめました</b></font>
* 今後はこちらを最新化するため、<font color="red"><b>最新情報はこちらをご確認くださ</b>い</font>
* 20万文字を超える超大作になっています!!

---

## まとめ記事
* [Flutter系の記事のまとめ](https://qiita.com/kazutxt/items/524acb1c134015682ccf)

## 動画編(兄弟記事)
* [Flutterではカメラ&ギャラリーから5行で動画が取得&再生できて感動した!!](https://qiita.com/kazutxt/items/cc03bf35aea3753a1e8a)

# はじめに
* 少し大げさかもしれないけれど、Flutterで一瞬でカメラを使った画像の制御ができて、嬉しくなったので、記事にしました。


# 画像
Flutterでは、スマホで撮影したり、ギャラリーに保存されている画像を利用するのが非常に簡単です。

## 本質的な3行
```dart
imagePicker.getImage(source: ImageSource.camera);　// カメラを起動して画像を撮影
_image = File(pickedFile.path) // 撮影した画像を表示
 Image.file(_image!) // 画像表示用のWidget
```


# 事前準備

## パッケージインストール

```yaml:pubspec.yml
image_picker: ^0.7.4
```

## iOS

```xml:info.plist
<key>NSPhotoLibraryUsageDescription</key>
<string>ライブラリ用権限</string>
<key>NSCameraUsageDescription</key>
<string>カメラ用権限</string>
<key>NSMicrophoneUsageDescription</key>
<string>マイク用権限</string>
```

## Android

Android 10（API レベル 29）以上の場合は対応は必要ありません。

```xml:AndroidManifest.xml
android:requestLegacyExternalStorage="true"
```

# 実装

カメラとギャラリーの2つの方法で、画像を取得して画面に表示するサンプルアプリです。

```dart: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: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, this.title}) : super(key: key);
  final String? title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  File? _image;
  final imagePicker = ImagePicker();
  Future getImageFromCamera() async {
    final pickedFile = await imagePicker.getImage(source: ImageSource.camera);
    setState(() {
      if (pickedFile != null) {
        _image = File(pickedFile.path);
      }
    });
  }
  Future getImageFromGarally() async {
    final pickedFile = await imagePicker.getImage(source: ImageSource.gallery);
    setState(() {
      if (pickedFile != null) {
        _image = File(pickedFile.path);
      }
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title!),
        ),
        body: Center(
            child: _image == null
                ? Text(
                    '写真を選択してください',
                    style: Theme.of(context).textTheme.headline4,
                  )
                : Image.file(_image!)),
        floatingActionButton:
            Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
          FloatingActionButton(
              onPressed: getImageFromCamera, child: Icon(Icons.photo_camera)),
          FloatingActionButton(
              onPressed: getImageFromGarally, child: Icon(Icons.photo_album))
        ]));
  }
}
```

カメラ/ギャラリーから写真を取得する部分は
`imagePicker.getImage(source: ImageSource.camera);`
`imagePicker.getImage(source: ImageSource.gallery);`
の部分で、極めてシンプルに実装できます。

あとは、`_image = File(pickedFile.path);`で取得したデータを設定し、` Image.file(_image!)`で表示しています。

# 動作確認

エミュレータではカメラは動きません。実機で動作を確認してください。

下記の動作確認のスクリーンショットは、複数の環境を組み合わせています。

## カメラを起動して撮影して表示
![pic1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/b8ae4ba4-2c3f-4c07-a30e-29b5c9bba049.png)

## フォトギャラリーから選択して表示
![pic2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/5b8d102c-376d-bb73-c664-db0a65a4cc5d.png)