Work with the camera in Flutter

    The ability to use the camera exists in many applications, and we all regularly use it. In Flutter, we can implement the work with the camera using two official plugins:



    There is a noticeable difference between them, and it is worth using them according to the situation:


    • cameraAllows you to interact with the cameras available to the device from your application and display the image in the widget. It is well suited for tasks when you need to "customize" the operation of the camera for the application.
    • image-pickerlaunches the camera application and returns an object of the type File(image or video file selected by the user) to your application. It also image-pickermakes it possible to select a file from those available on the device, while, as in the case of the camera, a separate application is launched, after which the selected object is returned to your application.



    Here you can see the source .




    camera


    1. Add the plugin to our project according to the instructions


    Additional settings for
    iOS OS
    Add the following lines to ios/Runner/Info.plist:


    NSCameraUsageDescriptionAccess to CameraNSMicrophoneUsageDescriptionAccess to Microphone

    Android
    Ensure that the minimum version of Android sdk in the file is android/app/build.gradle21 .


    minSdkVersion 21

    All necessary permissions will be requested when the application starts.


    Work on emulators
    In the case of iOS, we can not check the camera on the emulator, we need a "live" device.
    Android generates a mock (see image below), which replaces what the camera lens sees.


    Standard plug


    If you do not want to look at the standard plug

    In the emulator settings, select Advanced Settings and set it for the rear camera VirtualScene.

    We restart the emulator. Now the camera "shows" the virtual room, which can be moved with the mouse and wasd.

    Thanks to Tonn_Tamerlan for the tip.


    2. We pass to the code. First, we get all the available cameras using the function availableCameras.


    final cameras = await availableCameras();

    This function will return an array of descriptions ( ) of available cameras, where each element will contain the name of the camera (it can just be an index), type (back, front, external) and the angle by which the photo should be rotated so that it displays in its orientation.List


    To control the camera, we need an object-controller of the type CameraController, to determine which we must specify one of the received camera descriptions and resolution (low, medium, high).


    void _setCameraController(CameraDescription cameraDescription) async {
         _controller = CameraController(cameraDescription, ResolutionPreset.medium);
         ...
         await _controller.initialize();
         ...
         if (mounted) {
           setState(() {});
         }
    }

    Next, we initialize the controller and after making sure that the widget is "alive", we update the state of this widget. ( function text )


    We pass the initialized controller to the widget CameraPreview


         AspectRatio(
             aspectRatio: _controller.value.aspectRatio,
             child: CameraPreview(_controller))

    It is based CameraPreviewon a widget Textureresponsible for displaying pictures from the camera. Its dimensions are determined by the parent, so a widget approach AspectRatiothat determines the size of the child in a certain aspect ratio is a good approach . We get the ratio from the controller _controller.value.aspectRatio. As a result, in the interface we get a picture in the interface


    App view after controller initialization


    3. Now we can take a photo or shoot a video.
    a. We take a photo ( function text ) using the method takePicture(String path). It takes a picture and saves along the specified path.


    Future _takePhoto(BuildContext context) async {
         ...
         await _controller.takePicture(filePath);
         ...
    }

    To get the path, we need the official path_provider plugin and its method getApplicationDocumentsDirectory, which will return a private directory. Next, we determine the name of the directory to taste, if necessary, create it, and select the file name:


        final Directory extDir = await getApplicationDocumentsDirectory();
        final String dirPath = '${extDir.path}/Pictures/flutter_camera';
        await Directory(dirPath).create(recursive: true);
        final String filePath = '$dirPath/${_getTimestamp()}.jpg';

    Before taking a picture, it is advisable to verify that the controller is initialized and the picture is no longer taken.


    if (!_controller.value.isInitialized) {
         return null;
    }
    ...
    if (_controller.value.isTakingPicture) {
        return null;
    }

    The picture was taken, we have a way to it, it would be nice to see. Using a standard widget Image, object Fileand file path, we display the image on the screen.


    Image.file(File(filePath))

    Output the resulting snapshot


    b. When recording video ( function text ), we need two functions: startVideoRecording(String filePath)and stopVideoRecording().


    Future _startVideoRecording() async {
         ...
         await _controller.startVideoRecording(filePath);
        ...
    }
    Future _stopVideoRecording(BuildContext context) async {
        ...
        await _controller.stopVideoRecording();
        ...
    }

    startVideoRecordingwrites a video and saves according to the specified path (obtained by the same principle as with a photograph), stopVideoRecordingbut simply ends the recording process. Before you start recording, make sure that shooting is no longer in progress.


    if (_controller.value.isRecordingVideo) {
         return null;
    }

    As a result, we have a saved video and a path to it. To play it, you will need the video_player plugin . All the code associated with playing the video, taken out in a separate file .


    Record and play in the interface




    image-picker


    1. Add the plugin to our project according to the instructions


    Additional settings for
    iOS OS
    Add the following lines to ios/Runner/Info.plist:


    NSCameraUsageDescriptionAccess to CameraNSMicrophoneUsageDescriptionAccess to MicrophoneNSPhotoLibraryUsageDescriptionAccess to PhotoLibrary

    Work on emulators
    In iOS, we can not check the camera on the emulator, we need a "live" device.


    2.image-picker использует стандартное приложение для создания фото/видео или просмотра файлов. Для запуска нужного приложения необходимо воспользоваться функцией pickImage для фото или pickVideo и указать параметр source (источник).


    ...
    final File video = await ImagePicker.pickVideo(source: ImageSource.camera);
    final File photo = await ImagePicker.pickImage(source: ImageSource.gallery);
    // для pickImage можно еще указать максимальные показатели ширины и высоты, иначе изображение вернется в оригинальном размере
    ...

    Галерея и камера



    Выбранный файл получает наше приложение, но если ничего не было выбрано, то вернется null. Для показа картинки и видео используем те же подходы, что и в случае плагина camera. Для изображений виджет Image — в этот раз не надо оборачивать в File, так как мы изначально получили объект этого типа.


    Image.file(photo)

    Для видео плагин video_player. Весь код, связанный с проигрыванием видео, вынесен в отдельный файл.




    Заключение


    As you can see, it’s image-pickernoticeably easier to use and is great in cases where you just need to transfer the image or video to the application. camerait also provides us with all the necessary features for customizing the user’s work with the camera in your application.
    Thanks for reading!


    Also popular now: