Easiest Flutter Camera Plugin with Builtin UI. Supporting Capturing Images,Streaming Image

CamerAwesome 

๐Ÿ“ธ Embedding a camera experience within your own app shouldn't be that hard.
A flutter plugin to integrate awesome Android / iOS camera experience.
This package provides you with a fully customizable camera experience that you can use within your app.
Use our awesome built-in interface or customize it as you want.


Migration guide 

If you are migrating from version 1.x.x to 2.x.x, please read the migration guide.

Native features 

Here's all native features that cameraAwesome provides to the flutter side.

FeaturesAndroidiOS
๐Ÿ”– Ask permissionsโœ…โœ…
๐ŸŽฅ Record videoโœ…โœ…
๐Ÿ“น Multi camera (๐Ÿšง BETA)โœ…โœ…
๐Ÿ”ˆ Enable/disable audioโœ…โœ…
๐ŸŽž Take photosโœ…โœ…
๐ŸŒ† Photo live filtersโœ…โœ…
๐ŸŒค Exposure levelโœ…โœ…
๐Ÿ“ก Broadcast live image streamโœ…โœ…
๐Ÿงช Image analysis (barcode scan & more.)โœ…โœ…
๐Ÿ‘ Zoomโœ…โœ…
๐Ÿ“ธ Device flash supportโœ…โœ…
โŒ›๏ธ Auto focusโœ…โœ…
๐Ÿ“ฒ Live switching cameraโœ…โœ…
๐Ÿ˜ตโ€๐Ÿ’ซ Camera rotation streamโœ…โœ…
๐Ÿค Background auto stopโœ…โœ…
๐Ÿ”€ Sensor type switchingโ›”๏ธโœ…
๐Ÿชž Enable/disable front camera mirroringโœ…โœ…

๐Ÿ“–  Installation and usage 

Add the package in your pubspec.yaml 

dependencies:
  camerawesome: ^2.0.0-dev.1
  ...

Platform specific setup 

  • iOS

Add these on ios/Runner/Info.plist:


<key>NSCameraUsageDescription</key>
<string>Your own description</string>

<key>NSMicrophoneUsageDescription</key>
<string>To enable microphone access when recording video</string>

<key>NSLocationWhenInUseUsageDescription</key>
<string>To enable GPS location access for Exif data</string>
  • Android

Change the minimum SDK version to 21 (or higher) in android/app/build.gradle:

minSdkVersion 21

In order to be able to take pictures or record videos, you may need additional permissions depending on the Android version and where you want to save them. Read more about it in the official documentation.

WRITE_EXTERNAL_STORAGE is not included in the plugin starting with version 1.4.0.

If you want to record videos with audio, add this permission to your AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.yourpackage">
  <uses-permission android:name="android.permission.RECORD_AUDIO" />

  <!-- Other declarations -->
</manifest>

You may also want to save location of your pictures in exif metadata. In this case, add below permissions:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example.yourpackage">
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

  <!-- Other declarations -->
</manifest>

โš ๏ธ Overriding Android dependencies

Some of the dependencies used by CamerAwesome can be overriden if you have a conflict. Change these variables to define which version you want to use:

buildscript {
  ext.kotlin_version = '1.7.10'
  ext {
    // You can override these variables
    compileSdkVersion = 33
    minSdkVersion = 24 // 21 minimum
    playServicesLocationVersion = "20.0.0"
    exifInterfaceVersion = "1.3.4"
  }
  // ...
}

Only change these variables if you are sure of what you are doing.

For example, setting the Play Services Location version might help you when you have conflicts with other plugins. The below line shows an example of these conflicts:

java.lang.IncompatibleClassChangeError: Found interface com.google.android.gms.location.ActivityRecognitionClient, but class was expected

Import the package in your Flutter app 

import 'package:camerawesome/camerawesome_plugin.dart';

๐Ÿ‘Œ Awesome built-in interface 

Just use our builder.
That's all you need to create a complete camera experience within your app.

CameraAwesomeBuilder.awesome(
  saveConfig: SaveConfig.photoAndVideo(),
  onMediaTap: (mediaCapture) {
    OpenFile.open(mediaCapture.filePath);
  },
),

This builder can be customized with various settings:

  • A theme.
  • Builders for each part of the screen.
  • Initial camera setup.
  • Preview positioning.
  • Additional preview decoration.
  • And much more!

Here is an example:

Check the full documentation to learn more.


๐ŸŽจ Creating a custom interface 

If the awesome() factory is not enough, you can use custom() instead.

It provides a builder property that lets you create your own camera experience.

The camera preview will be visible behind what you will provide to the builder.

CameraAwesomeBuilder.custom(
  saveConfig: SaveConfig.photo(),
  builder: (state, previewSize, previewRect) {
    // create your interface here
  },
)

See more in documentation

Working with the custom builder 

Here is the definition of our builder method.

typedef CameraLayoutBuilder = Widget Function(CameraState cameraState, PreviewSize previewSize, Rect previewRect);some states work ?

Using the state you can do anything you need without having to think about the camera flow

  • On app start we are in PreparingCameraState
  • Then depending on the initialCaptureMode you set you will be PhotoCameraState or VideoCameraState
  • Starting a video will push a VideoRecordingCameraState
  • Stopping the video will push back the VideoCameraState
    Also if you want to use some specific function you can use the when method so you can write like this.
state.when(
  onPhotoMode: (photoState) => photoState.start(),
  onVideoMode: (videoState) => videoState.start(),
  onVideoRecordingMode: (videoState) => videoState.pause(),
);

See more in documentation


๐Ÿ”ฌ Analysis mode 

Use this to achieve:

  • QR-Code scanning.
  • Facial recognition.
  • AI object detection.
  • Realtime video chats.
  • And much more ๐Ÿคฉ

You can check examples using MLKit inside the example directory. The above example is from ai_analysis_faces.dart. It detects faces and draw their contours.

It's also possible to use MLKit to read barcodes:

Check ai_analysis_barcode.dart and preview_overlay_example.dart for examples or the documentation.

How to use it 

CameraAwesomeBuilder.awesome(
  saveConfig: SaveConfig.photo(),
  onImageForAnalysis: analyzeImage,
  imageAnalysisConfig: AnalysisConfig(
        // Android specific options
        androidOptions: const AndroidAnalysisOptions.nv21(
            // Target width (CameraX will chose the closest resolution to this width)
            width: 250,
        ),
        // Wether to start automatically the analysis (true by default)
        autoStart: true,
        // Max frames per second, null for no limit (default)
        maxFramesPerSecond: 20,
    ),
)

MLkit recommends using nv21 format for Android.
bgra8888 is the iOS format For machine learning you don't need full-resolution images (720 or lower should be enough and makes computation easier)

Learn more about the image analysis configuration in the documentation .

Check also detailed explanations on how to use MLKit to read barcodes and detect faces.

โš ๏ธ On Android, some devices don't support video recording and image analysis at the same time.

  • If they don't, image analysis will be ignored.
  • You can check if a device has this capability by using CameraCharacteristics .isVideoRecordingAndImageAnalysisSupported(Sensors.back).

๐Ÿฝ Updating Sensor configuration 

Through state you can access to a SensorConfig class.
 

FunctionComment
setZoomchange zoom
setFlashModechange flash between NONE,ON,AUTO,ALWAYS
setBrightnesschange brightness level manually (better to let this auto)
setMirrorFrontCameraset mirroring for front camera

All of these configurations are listenable through a stream so your UI can automatically get updated according to the actual configuration.

๐ŸŒ† Photo live filters 

Apply live filters to your pictures using the built-in interface:

You can also choose to use a specific filter from the start:

CameraAwesomeBuilder.awesome(
  // other params
  filter: AwesomeFilter.AddictiveRed,
  availableFilters: ...
)

Or set the filter programmatically:

CameraAwesomeBuilder.custom(
  builder: (cameraState, previewSize, previewRect) {
    return cameraState.when(
      onPreparingCamera: (state) =>
      const Center(child: CircularProgressIndicator()),
      onPhotoMode: (state) =>
          TakePhotoUI(state, onFilterTap: () {
            state.setFilter(AwesomeFilter.Sierra);
          }),
      onVideoMode: (state) => RecordVideoUI(state, recording: false),
      onVideoRecordingMode: (state) =>
          RecordVideoUI(state, recording: true),
    );
  },
)

See all available filters in the documentation.

[!TIP] By default the awesome ui setup has a filter list but you can pass an empty list to remove it

๐Ÿ“ท ๐Ÿ“ท Concurrent cameras 

๐Ÿšง Feature in beta ๐Ÿšง Any feedback is welcome!

In order to start using CamerAwesome with multiple cameras simulatenously, you need to define a SensorConfig that uses several sensors. You can use the SensorConfig.multiple() constructor for this:

CameraAwesomeBuilder.awesome(
    sensorConfig: SensorConfig.multiple(
        sensors: [
            Sensor.position(SensorPosition.back),
            Sensor.position(SensorPosition.front),
        ],
        flashMode: FlashMode.auto,
        aspectRatio: CameraAspectRatios.ratio_16_9,
    ),
    // Other params
)

This feature is not supported by all devices and even when it is, there are limitations that you must be aware of.

Check the details in the dedicated documentation.

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add camerawesome

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  camerawesome: ^2.0.0+1

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:camerawesome/camerawesome_plugin.dart';
import 'package:camerawesome/pigeon.dart';

example/lib/main.dart

import 'dart:io';

// import 'package:better_open_file/better_open_file.dart';
import 'package:camerawesome/camerawesome_plugin.dart';
import 'package:camerawesome/pigeon.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'utils/file_utils.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'camerAwesome',
      home: CameraPage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: Colors.white,
        child: CameraAwesomeBuilder.awesome(
          saveConfig: SaveConfig.photoAndVideo(
            initialCaptureMode: CaptureMode.photo,
            mirrorFrontCamera: true,
            photoPathBuilder: (sensors) async {
              final Directory extDir = await getTemporaryDirectory();
              final testDir = await Directory(
                '${extDir.path}/camerawesome',
              ).create(recursive: true);
              if (sensors.length == 1) {
                final String filePath =
                    '${testDir.path}/${DateTime.now().millisecondsSinceEpoch}.jpg';
                return SingleCaptureRequest(filePath, sensors.first);
              } else {
                // Separate pictures taken with front and back camera
                return MultipleCaptureRequest(
                  {
                    for (final sensor in sensors)
                      sensor:
                          '${testDir.path}/${sensor.position == SensorPosition.front ? 'front_' : "back_"}${DateTime.now().millisecondsSinceEpoch}.jpg',
                  },
                );
              }
            },
            videoOptions: VideoOptions(
              enableAudio: true,
              ios: CupertinoVideoOptions(
                fps: 10,
              ),
              android: AndroidVideoOptions(
                bitrate: 6000000,
                fallbackStrategy: QualityFallbackStrategy.lower,
              ),
            ),
            exifPreferences: ExifPreferences(saveGPSLocation: true),
          ),
          sensorConfig: SensorConfig.single(
            sensor: Sensor.position(SensorPosition.back),
            flashMode: FlashMode.auto,
            aspectRatio: CameraAspectRatios.ratio_4_3,
            zoom: 0.0,
          ),
          enablePhysicalButton: true,
          // filter: AwesomeFilter.AddictiveRed,
          previewFit: CameraPreviewFit.contain,
          onMediaTap: (mediaCapture) {
            mediaCapture.captureRequest.when(
              single: (single) {
                debugPrint('single: ${single.file?.path}');
                single.file?.open();
              },
              multiple: (multiple) {
                multiple.fileBySensor.forEach((key, value) {
                  debugPrint('multiple file taken: $key ${value?.path}');
                  value?.open();
                });
              },
            );
          },
          availableFilters: awesomePresetFiltersList,
        ),
      ),
    );
  }
}

Download details:

Author: apparence.io

Source: https://github.com/Apparence-io/camera_awesome

#flutter #android #ios

Easiest Flutter Camera Plugin with Builtin UI. Supporting Capturing Images,Streaming Image
4.75 GEEK