LoginSignup
4

More than 3 years have passed since last update.

posted at

Flutter 正方形にカメラの映像を表示させるサンプル

実現したいこと

正方形にカメラの映像を表示させる

動作の様子

IMG_5485 2.2020-01-30 15_06_52.gif

動作コード

こちらに一式用意しています。
https://github.com/quqjp/flutter-test

コード箇所はこちら。
https://github.com/quqjp/flutter-test/tree/master/lib/sample4

利用プラグイン

Camera Plugin
https://pub.dev/packages/camera

installing に従い導入する
https://pub.dev/packages/camera#-installing-tab-

コード

FittedBoxで囲ってセンタリングすることで、映像の中心を保ちつつ正方形にマスク処理できた。
FittedBox内に、AspectRatioを用いてCameraPreviewを配置しようとしたが、うまく行かず。
幅は親要素で決まるので、わざわざMediaQueryでsizeを取得したくなかったが
FittedBox内は、親要素幅を引き継いだWidget配置ができなかったためこのようにした。

映像のセンターが正しく中心に表示されているか確認のため、
右上の★ボタンを押すことで、表示の比率を変えるようにしている。

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

//third party package
import 'package:camera/camera.dart';

//my package

//same package

//
// カメラの映像を正方形で表示させるサンプル
//
class Sample4Page extends StatefulWidget {
  Sample4Page({Key key, this.title}) : super(key: key);

  // タイトル
  final String title;

  @override
  _State createState() => _State();
}

class _State extends State<Sample4Page> {
  //カメラリスト
  List<CameraDescription> _cameras;

  //カメラコントローラ
  CameraController _controller;

  //
  double _aspectRatio = 1.0;

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

    initCamera();
  }

  //
  // カメラを準備
  //
  initCamera() async {
    _cameras = await availableCameras();

    if (_cameras.length != 0) {
      _controller = CameraController(_cameras[0], ResolutionPreset.high);
      _controller.initialize().then((_) {
        if (!mounted) {
          return;
        }

        //カメラ接続時にbuildするようsetStateを呼び出し
        setState(() {});
      });
    }
  }

  //
  // カメラの表示比率を変更する
  //
  _toggle() {
    setState(() {
      _aspectRatio = _aspectRatio == 1.0 ? 0.7 : 1.0;
    });
  }

  ///
  ///
  ///
  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size.width;

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.star),
            onPressed: () {
              _toggle();
            },
          ),
        ],
      ),
      //
      body: Container(
        alignment: Alignment.center,
        child: AspectRatio(
          aspectRatio: _aspectRatio,
          child: FittedBox(
            alignment: Alignment.center,
            fit: BoxFit.fitWidth,
            child: _controller != null && _controller.value.isInitialized
                ? Container(
                    width: size,
                    height: size / _controller.value.aspectRatio,
                    child: CameraPreview(_controller))
                : Container(),
          ),
        ),
      ),
    );
  }
}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
4