Put your feet on the ground

主にプログラミングのお話。

Flutterでカメラ撮影

Flutterでカメラを使い、撮影した画像を画面に表示する。

ちなみにVSCodeを使っています。
一番下にソース全文載せてあります。

  • image_pickerライブラリを使う

pub.dartlang.org

Flutter Team製だから安心。

pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^0.1.2
  image_picker: ^0.4.10 // 追加

コマンドラインで以下を実行(VSCodeならpubspec.yamlを保存すれば自動で走る)

flutter packages get



  • iOSはinfo.plist内に必要に応じて以下のキーと説明を登録する

NSPhotoLibraryUsageDescription - あなたのアプリが写真ライブラリの許可を必要とする理由を説明してください。これはビジュアルエディタのプライバシー - 写真ライブラリ使用説明と呼ばれています。

NSCameraUsageDescription - あなたのアプリがカメラにアクセスする必要がある理由を説明します。これはビジュアルエディタのプライバシー - カメラ使用説明と呼ばれます。

  • 適当に画面を作る

image_picker_view.dart

import 'dart:io';

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

class ImagePickerView extends StatefulWidget {
  @override
  State createState() {
    return ImagePickerViewState();
  }
}

class ImagePickerViewState extends State {
  File imageFile;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('ImagePicker'),
          backgroundColor: Theme.of(context).primaryColor,
        ),
        body: Container(
          alignment: Alignment.center,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              (imageFile == null)
                  ? Icon(Icons.no_sim)
                  : Image.file(
                      imageFile,
                      height: 100.0,
                      width: 100.0,
                    ),
              Container(
                  padding: EdgeInsets.all(10.0),
                  child: RaisedButton(
                    child: Text('カメラで撮影'),
                    onPressed: () {},
                  )),
              Container(
                  padding: EdgeInsets.all(10.0),
                  child: RaisedButton(
                    child: Text('ライブラリから選択'),
                    onPressed: () {},
                  )),
            ],
          ),
        ));
  }

f:id:karmactonics:20180901002520p:plain:w200

  • クラスにimage_pickerをインポートする
import 'package:image_picker/image_picker.dart';
  • カメラを呼び出す処理を書く
// カメラまたはライブラリから画像を取得
  void _getImageFromDevice(ImageSource source) async {
    // 撮影/選択したFileが返ってくる
    var imageFile = await ImagePicker.pickImage(source: source);
    // Androidで撮影せずに閉じた場合はnullになる
    if (imageFile == null) {
      return;
    }
    setState(() {
      this.imageFile = imageFile;
    });
  }
}

こんな感じ。
カメラとライブラリそれぞれから選択できるようにする。
ImageSource.camera => カメラ
ImageSource.gallery => ライブラリ
から選択できる。

  • ボタンのonPressedブロックで、上記のメソッドを呼ぶ。
Container(
    padding: EdgeInsets.all(10.0),
    child: RaisedButton(
      child: Text('カメラで撮影'),
      onPressed: () {
        _getImageFromDevice(ImageSource.camera); // New Line
      },
    )),
Container(
    padding: EdgeInsets.all(10.0),
    child: RaisedButton(
      child: Text('ライブラリから選択'),
      onPressed: () {
        _getImageFromDevice(ImageSource.gallery); // New Line
      },
    )),
  • 実行

f:id:karmactonics:20180901010616g:plain

めちゃ簡単。

  • ソース全文
import 'dart:io';

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

class ImagePickerView extends StatefulWidget {
  @override
  State createState() {
    return ImagePickerViewState();
  }
}

class ImagePickerViewState extends State {
  File imageFile;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('ImagePicker'),
          backgroundColor: Theme.of(context).primaryColor,
        ),
        body: Container(
          alignment: Alignment.center,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              (imageFile == null)
                  ? Icon(Icons.no_sim)
                  : Image.file(
                      imageFile,
                      height: 100.0,
                      width: 100.0,
                    ),
              Container(
                  padding: EdgeInsets.all(10.0),
                  child: RaisedButton(
                    child: Text('カメラで撮影'),
                    onPressed: () {
                      _getImageFromDevice(ImageSource.camera);
                    },
                  )),
              Container(
                  padding: EdgeInsets.all(10.0),
                  child: RaisedButton(
                    child: Text('ライブラリから選択'),
                    onPressed: () {
                      _getImageFromDevice(ImageSource.gallery);
                    },
                  )),
            ],
          ),
        ));
  }

// カメラまたはライブラリから画像を取得
  void _getImageFromDevice(ImageSource source) async {
    // 撮影/選択したFileが返ってくる
    var imageFile = await ImagePicker.pickImage(source: source);
    // Androidで撮影せずに閉じた場合はnullになる
    if (imageFile == null) {
      return;
    }
    setState(() {
      this.imageFile = imageFile;
    });
  }
}