[Flutter] Take a photo by Camera plugin

[Flutter] Take a photo by Camera plugin

2023-07-15 hit count image

Let's see how to use the Camera plugin to take a photo Flutter in Flutter.

Outline

To use the camera function such as taking a photo in Flutter, you need to use the Camera plugin provided by Flutter.

In this blog post, I will introduce how to take a photo using the Camera plugin. You can see the full source introduced here on GitHub.

Create proejct

To see how to take a photo in Flutter using the Camera plugin, create a new Flutter project using the following command.

flutter create camera_example

Install Camera plugin

After creating a new Flutter project, execute the following command to install the Camera plugin.

flutter pub add camera

iOS configuration

To use the Camera plugin in iOS, you need to set the permission. Open the ios/Runner/Info.plist file and add the permission as follows.

  ...
	<key>NSCameraUsageDescription</key>
	<string>Camera permission is required.</string>
	<key>NSMicrophoneUsageDescription</key>
	<string>Microphone permission is required.</string>
</dict>
</plist>

Android configuration

The Camera plugin only supports Android SDK 21 or higher. So, you need to modify the minSdkVersion. Open the android/app/build.gradle file and modify the minSdkVersion as follows.

  ...
  defaultConfig {
    ...
    minSdkVersion 21
    ...
  }
  ...

Implement taking a photo feature

In this blog post, I will introduce how to implement a screen that takes a photo using the Camera plugin and a screen that shows the taken photo.

Take a photo

To implement a screen that takes a photo using the Camera plugin, create a lib/camera_screen.dart file and modify it as follows.

import 'package:camera/camera.dart';
import 'package:camera_example/photo_preview.dart';
import 'package:flutter/material.dart';

class CameraScreen extends StatefulWidget {
  const CameraScreen({super.key});

  @override
  State<CameraScreen> createState() => _CameraScreenState();
}

class _CameraScreenState extends State<CameraScreen> {
  CameraController? _cameraController;
  bool _isCameraReady = false;

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

    availableCameras().then((cameras) {
      if (cameras.isNotEmpty && _cameraController == null) {
        _cameraController = CameraController(
          cameras.first,
          ResolutionPreset.medium,
        );

        _cameraController!.initialize().then((_) {
          setState(() {
            _isCameraReady = true;
          });
        });
      }
    });
  }

  void _onTakePicture(BuildContext context) {
    _cameraController!.takePicture().then((image) {
      Navigator.of(context).push(
        MaterialPageRoute(
          builder: (context) => PhotoPreview(
            imagePath: image.path,
          ),
        ),
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Take a photo')),
      body: SafeArea(
        child: Column(
          children: [
            Expanded(
              flex: 1,
              child: _cameraController != null && _isCameraReady
                  ? CameraPreview(_cameraController!)
                  : Container(
                      color: Colors.grey,
                    ),
            ),
            Padding(
              padding: const EdgeInsets.all(16),
              child: ElevatedButton(
                onPressed: _cameraController != null
                    ? () => _onTakePicture(context)
                    : null,
                child: const Text('Take a photo'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Let’s take a look at the code that uses the Camera plugin in detail.

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

  availableCameras().then((cameras) {
    if (cameras.isNotEmpty && _cameraController == null) {
      _cameraController = CameraController(
        cameras.first,
        ResolutionPreset.medium,
      );

      _cameraController!.initialize().then((_) {
        setState(() {
          _isCameraReady = true;
        });
      });
    }
  });
}
...

First, use the Camera plugin’s availableCameras function to check if the camera is available. If the camera is available, initialize the CameraController.

...
Expanded(
  flex: 1,
  child: _cameraController != null && _isCameraReady
      ? CameraPreview(_cameraController!)
      : Container(
          color: Colors.grey,
        ),
),
...

After initializing the CameraController, use the CameraController and the CameraPreview widget provided by the Camera plugin to configure the camera shooting screen.

...
void _onTakePicture(BuildContext context) {
  _cameraController!.takePicture().then((image) {
    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) => PhotoPreview(
          imagePath: image.path,
        ),
      ),
    );
  });
}
...

Finally, use the takePicture function of the CameraController to implement the photo shooting function. The photo shooting result is returned as XFile, and the path of the photo image returned in this way is passed to the screen to display the photo shooting result.

Display photo shooting result

To display the photo taken using the Camera plugin on the screen, create a lib/photo_preview.dart file and modify it as follows.

import 'dart:io';

import 'package:flutter/material.dart';

class PhotoPreview extends StatelessWidget {
  final String imagePath;

  const PhotoPreview({required this.imagePath, super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Preview')),
      body: Container(
        color: Colors.grey,
        child: Center(
          child: Image.file(
            File(imagePath),
          ),
        ),
      ),
    );
  }
}

The screen receives the path of the photo taken using the Camera plugin, so use Image.fil to display the path of the received photo.

...
child: Image.file(
  File(imagePath),
),
...

main.dart

To use the screens created in this way, modify the lib/main.dart file as follows.

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Camera Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const CameraScreen(),
    );
  }
}

Check

We’ve implemented the photo shooting function using the Camera plugin in Flutter. Now let’s run the app and see if the photo shooting function works properly.

The camera feature can’t be used in the simulator(emulator), so you need to run the app using an actual device. When you run the app, the following screen will appear asking for permission to use the camera.

Flutter Camera plugin - camera permission on iOS

When you press OK to set the permission, the following screen will appear asking for permission to use the microphone.

Flutter Camera plugin - microphone permission on iOS

When you set all the permissions, you can see that the camera shooting screen is displayed as follows.

Flutter Camera plugin - take a photo view on iOS

Finally, when you press the Take a photo button to take a photo, you can see that the taken photo is displayed on the screen as follows.

Flutter Camera plugin - image preview on iOS

Test code

If you want to know how to write a test code for the photo shooting feature implemented using the Camera plugin, please refer to the following blog.

Completed

Done! We’ve seen how to implement the photo shooting function using the Camera plugin in Flutter. The official documentation also introduces how to implement the photo shooting function using the Camera plugin, so it would be nice to refer to it.

Was my blog helpful? Please leave a comment at the bottom. it will be a great help to me!

App promotion

You can use the applications that are created by this blog writer Deku.
Deku created the applications with Flutter.

If you have interested, please try to download them for free.

Posts