How to add Camera support to a Flutter app

Natalia Majkowska-Stewart
Brains & Beards
Published in
5 min readApr 18, 2019

I’d say 90% of the apps I’ve developed required a camera feature. It can be anything from capturing pictures, loading image paths from a gallery, to manipulating images. In this tutorial, I’m going to show you how to easily add a camera feature to a Flutter app.

Rolfix medium format film camera

What Are We Building?

We’re going to be extending upon our existing Beers App. Our aim is to be able to add new beers to our application. It will be important to capture an image of the beer we’re adding. We’ll also add some text inputs to collect the name, country of origin, and the beer’s ABV. To help put this all together, we’re going to create a new AddBeerScreen widget.

Basic functionality

When I had to figure this out, the first thing I did was search for a camera package in Flutter. I came across the following:

As per the documentation, we have to set the minSdkVersion to 21 or higher in android/app/build.gradle for an Android app. For iOS, we need to edit ios/Runner/Info.plist and add the following key / values for camera permissions. For a mobile application to have access to the camera, the user has to grant it permissions.

<key>NSCameraUsageDescription</key>
<string>Can I use the camera please?</string>
<key>NSMicrophoneUsageDescription</key>
<string>Can I use the mic please?</string>

Before we get started creating a camera widget, we need to add camera dependencies to pubspec.yaml. Please follow the instructions for the camera package to install it.

dependencies:
flutter:
sdk: flutter
http: 0.12.0+1
camera: ^0.4.2

First, I created a camera folder in the screens directory and added a camera.dart. The code in the documentation doesn’t fit my structure perfectly, so you’ll want to modify the implementation slightly:

We’ll also update the bottom navigation, instantiating a new instance of the CameraWidget:

Here is the result:

New Beer tab

Add Beer Screen

Okay, we have a basic version working, but what we want to achieve during this tutorial is much more. Here is the view that we’re going for:

  1. The whole view needs to be in a scrolling widget. We need this for a simple reason — our view has inputs so if we want to scroll down to reach them we need a SingleChildScrollView. This widget lets us build a view, which automatically has a scrolling function. SingleChildScrollView creates a box in which a single widget can be scrolled.
  2. Camera view with a preview of the captured picture.
  3. Buttons for switching between front and back camera.
  4. Inputs for beer name, country name and ABV* and a blue button for submit.

*Alcohol by volume (abbreviated as ABV, abv, or alc/vol) is a standard measure of how much alcohol (ethanol) is contained in a given volume of an alcoholic beverage (expressed as a volume percent).

The first thing we need to declare are some values:

  • scaffoldKey — key which we need to display errors using scaffoldKey.currentState.showSnackBar.
  • cameras — we will keep a reference for available cameras
  • controller — to show the camera preview on the screen
  • isReady, showCamera, imagePath — variables for keeping state and the image path
  • nameController, countryController, abvController — input controllers

Next, we need to initialise the view’s state. It is very important for us to first check for an available camera. Camera.dart offers an asynchronous method for that. The setupCameras method also initialises CameraController and manages the isReady state.

When our cameras are initialised, it’s time to add a scrollable layout. I use SingleChildScrollView. I then add a Column widget with the camera preview and image preview. There is also a section for the camera capture button. After that, we have a camera options widget and input’s widget.

Let’s start with the cameraPreviewWidget. This method returns an AspectRatio widget, which is responsible for returning the child with a specific aspect ratio. Our child here is a CameraPreview widget.

If we have a camera, we also need a section to show the picture that was taken. The imagePreviewWidget is responsible for this. Basically, it is just a container with SizedBox for displaying an Image from the imagePath. The image that was taken is always saved to the phone’s memory, so for displaying the image, I use Image.file.

The next widget is simply a Row with an icon. The Icon has an onPressed method. If the camera controller isInitialized, the user can call onTakePictureButtonPressed.

The onTakePictureButtonPressed method is asynchronous and is responsible for creating a directory with a specific path. This file path is used for image captures. The image will be saved to the filePath.

Not every picture is perfect, so to give the user an opportunity to edit the picture, I’ve also added a editCaptureControlRowWidaget. After the button is pressed, the camera will become visible again and the user can retake the picture.

The next section contains two buttons which represent the camera options. A user can choose between the front or back camera. The cameraOptionsWidget returns a Row widget with SizedBoxes containing Radio Icons.

The radio button has an onChanged function, where I call the onNewCameraSelected method. This method reinitialised the controller with the current cameraDescription.

And finally, it’s time for the last section. To create a beer in app, we need some inputs where user can type in the information. We use for it a simple column with children that render Padding widgets with TextField widgets.

Summary

And here’s the final result! We’re able to switch between the front and rear cameras, take a picture and add some extra information in the input fields:

demo

After reading this tutorial, I hope this makes it a bit easier implementing a camera feature in your applications. Thankfully, implementing a camera feature in a Flutter app isn’t so difficult, but there are a few differences in building the camera layout compared to other technologies, such as ReactNative. If you like my tutorial, visit our blog and there you’ll find Flutter, React Native, GraphQL and other articles.

Stay tuned because the next Flutter article is coming… 🐺

PS. You can also download the full source code.

--

--

Natalia Majkowska-Stewart
Brains & Beards

React and React Native developer in Brains & Beards. Instagram: mobile_dev_girl