【超簡単】Flutterでiosのカメラ使ってみた

# 作るもの
flutter初めたての初心者でも作れる簡単な、写真を選択して表示する簡単なiosアプリを作成しますー！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/07e47825-4c92-af0f-189c-0f06f1a923db.png" width="45%">  <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/412c19bf-8fc9-3688-d60e-ff1944631157.png" width="45%">

コードはこちら

https://github.com/naoya25/qiita-camera-app.git

# flutterアプリの作成
```bash
flutter create camera_app
cd camera_app
```

# image_pickerのインストール
> 公式: https://pub.dev/packages/image_picker/install
```bash
flutter pub add image_picker
```
`pubspec.yaml`に`image_picker`が追加されています
```pubspec.yaml
  image_picker: ^1.0.7
```

# video_playerのインストール
image_pickerと同様にvideo_playerもインストールします
```bash
flutter pub add video_player
```
```pubspec.yaml
  image_picker: ^1.0.7
  video_player: ^2.8.3
```

# iosのカメラの設定
まずはiosのカメラと写真フォルダへのアクセス権限の設定をします
```diff:ios/Runner/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
+	<key>NSPhotoLibraryUsageDescription</key>
+	<string>フォトライブラリを利用する理由を記載</string>
+	<key>NSCameraUsageDescription</key>
+	<string>カメラを利用する理由を記載</string>
+	<key>NSMicrophoneUsageDescription</key>
+	<string>マイクを利用する理由を記載</string>

	<!-- 略 -->
</dict>
</plist>
```


```dart:lib/main.dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

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

class MyApp extends StatelessWidget {
  // 略
}

class MyHomePage extends StatefulWidget {
  // 略
}

class _MyHomePageState extends State<MyHomePage> {
  // カメラの処理
  XFile? _image;
  final ImagePicker _picker = ImagePicker();

  // カメラから画像を指定する関数
  Future<void> _getImageFromCamera() async {
    final file = await _picker.pickImage(source: ImageSource.camera);
    setState(() {
      if (file != null) {
        _image = XFile(file.path);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: _image == null
            ? const Text("写真を撮ってね")
            : Image.file(File(_image!.path)),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _getImageFromCamera,
        child: const Icon(Icons.photo_camera),
      ),
    );
  }
}
```

iosシミュレータを起動して実行するとこんな感じになりました
わからない方は[こちら](https://zenn.dev/tatsuyasusukida/scraps/6d3bccc8c1bdf7)をみてみてください
![simulator_screenshot_58F77114-0340-4F80-A5EE-AADC316DEBAE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/f0907493-70b4-ab2f-fc27-669068f7949f.png)

カメラボタンを押すとエラーが出ました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/27d49783-4ddb-091c-2c17-5270f5eb3eca.png)
おそらくシミュレータなので利用可能なカメラが存在しなかったからかと思います
実機で動かすとうまくいけてることが確認できます
実機での動かし方は[こちら](https://dev.classmethod.jp/articles/debugging-flutter-app-on-iphone-device-connected-to-macbook/)の記事などを参考にしてください

# 写真フォルダの設定
カメラの設定と同じように写真フォルダ用の関数を追加していきます
```diff_dart:lib/main.dart
import 'dart:io';

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

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

class MyApp extends StatelessWidget {
  // 略
}

class MyHomePage extends StatefulWidget {
  // 略
}

class _MyHomePageState extends State<MyHomePage> {
  // カメラの処理
  XFile? _image;
  final ImagePicker _picker = ImagePicker();

  // カメラから画像を指定する関数
  Future<void> _getImageFromCamera() async {
    // 略
  }

  // 写真フォルダから画像を指定する関数
+  Future<void> _getImageFromGallery() async {
+    final file = await _picker.pickImage(source: ImageSource.gallery);
+    setState(() {
+      if (file != null) {
+        _image = XFile(file.path);
+      }
+    });
+  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: _image == null
            ? const Text("写真を撮ってね")
            : Image.file(File(_image!.path)),
      ),
+      floatingActionButton: Column(
+        mainAxisSize: MainAxisSize.min,
+        children: [
+        FloatingActionButton(
+          onPressed: _getImageFromCamera,
+          child: const Icon(Icons.photo_camera),
+        ),
+        FloatingActionButton(
+          onPressed: _getImageFromGallery,
+          child: const Icon(Icons.photo_album),
+        ),
+      ]),
    );
  }
}
```
実行すると右下のfloatingActionButtonが増えていると思います
![simulator_screenshot_24F3CE51-1E62-432A-A84D-398316A30ADB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/ad5af7c6-93eb-20ab-5f97-6307b6d46cff.png)
下の写真フォルダ用のボタンをクリックすると写真を表示することができました
![simulator_screenshot_8DFD98C2-B1F6-4F85-B212-865AB874DDC9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/b235d3a7-5ac8-9803-9963-9eb1f22f3e0d.png)

# まとめ
ここまでで以上です
カメラ起動できなかったのはダメダメでしたが、flutter初心者でも簡単に写真を扱えたかなと思います
ご指摘等あればコメントお願いします
終わり〜〜
ばいちゃ〜〜

# エラー日記
#### 1. Image.file is not supported on Flutter Web
chromeで、`Image.file(File(_image!.path))`を使って画像を表示しようとしたら怒られました
僕の場合は、iosシミュレータを使って動かしましたが、どうしてもchromeで動かしたいときは代わりにImage.assetかImage.networkを使用すると良いみたいですね
"Image.file is not supported on Flutter Web. Consider using either Image.asset or Image.network instead."

# 参考記事
https://zenn.dev/kazutxt/books/flutter_practice_introduction/viewer/22_chapter3_camera

https://qiita.com/ling350181/items/916ab3174c3e0dfadb00

https://zenn.dev/tatsuyasusukida/scraps/6d3bccc8c1bdf7

https://pub.dev/packages/image_picker