Help us understand the problem. What is going on with this article?

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(),
          ),
        ),
      ),
    );
  }
}
quqjp
フリーランスフロントエンドエンジニア。ブログ・note執筆、個人開発(ツール系アプリ)にも取り組んでいます。 出版社・Web制作会社にてサービスの立ち上げや広告系キャンペーンサイト等のフロントエンド実装に携わる→独立→フリーランス9年目。
https://twitter.com/quqjp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away