概要
Flutterを使用してカメラを作成してみた。
開発環境
OS | Windows11 |
Editor | VS Code |
Flutter Ver. | 3.0.5 |
使用するパッケージを追加
camera pub.dev
dependencies: flutter: sdk: flutter camera: ^0.10.0+4
設定
Androidの設定
android/app/build.gradle
ファイルのminSdkVersion
を21以上に設定する。
android { defaultConfig { // ... minSdkVersion 21 // ... } }
iOSの設定
iOS10.0以降で使用可能。
Info.plist
に以下を追加。
<dict> ... <key>NSCameraUsageDescription</key> <string>カメラの使用許可</string> <key>NSMicrophoneUsageDescription</key> <string>マイクの使用許可</string> ... </dict>
実装
カメラの取得
利用可能なカメラのリストを取得する。
初期化の確認は runApp
の前でのみ可能。
Future<void> main() async { // プラグインの初期化を確認 WidgetsFlutterBinding.ensureInitialized(); // カメラのリストを取得 final cameras = await availableCameras(); // 1つ目のカメラを取得 final firstCamera = cameras.first; runApp(MyApp(camera: firstCamera)); }
CameraControllerを作成および初期化
CameraController
を作成して、初期化を行う。
// カメラ表示用の画面 class CameraScreen extends StatefulWidget { const CameraScreen({super.key, required this.camera}); final CameraDescription camera; @override CemeraScreenState createState() => CemeraScreenState(); } class CemeraScreenState extends State<CameraScreen> { late CameraController _controller; late Future<void> _initializeControllerFuture; @override void initState() { super.initState(); // CameraControllerを作成 _controller = CameraController( // カメラを設定 widget.camera, // 解像度を定義 ResolutionPreset.max ); // コントローラーを初期化 _initializeControllerFuture = _controller.initialize(); } @override void dispose() { // コントローラーを破棄 _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( // ... ); } }
CameraPreviewを使用してカメラの映像を表示
CameraPreview
ウィジェットを使用してカメラの映像を表示する。
class CemeraScreenState extends State<CameraScreen> { // ... @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('カメラ')), body: FutureBuilder<void>( future: _initializeControllerFuture, builder: (context, snapshot) { if(snapshot.connectionState == ConnectionState.done) { // 接続が完了したらカメラの映像を表示 return Container( color: Colors.black, alignment:Alignment.topCenter, child: CameraPreview(_controller), ); }else{ // 完了していなかった場合、インジケータを表示 return const Center(child: CircularProgressIndicator()); } }, ) ); } }
撮影機能の作成
撮影ボタンを追加する。
撮影が完了したら新しい画面を作成し、写真を表示。
class CemeraScreenState extends State<CameraScreen> { // ... @override Widget build(BuildContext context) { return Scaffold( // ... floatingActionButton: FloatingActionButton( onPressed: () async { try { // カメラの初期化を確認 await _initializeControllerFuture; // フラッシュをOFF _controller.setFlashMode(FlashMode.off); // 写真の撮影 final image = await _controller.takePicture(); // Stateオブジェクトがマウントされていない場合はreturn if (!mounted) return; // 写真が撮影されたら画面を切り替え表示 await Navigator.of(context).push(MaterialPageRoute( builder: (context) => DisplayPictureScreen(imagePath: image.path))); } catch (e) { print(e); } }, child: const Icon(Icons.camera_alt), ), ); } } // 撮影した写真を表示するウィジェット class DisplayPictureScreen extends StatelessWidget { final String imagePath; const DisplayPictureScreen({super.key, required this.imagePath}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('写真')), body: Container( color: Colors.black, alignment: Alignment.topCenter, child: Image.file(File(imagePath))), ); } }