CamerAwesome Documentation

repository·master·Indexed 22 days ago

https://github.com/apparence-io/camerawesome

A Flutter plugin for Android and iOS providing a customizable camera experience. It features a ready-to-use 'awesome' UI and a low-level custom builder for full control. Key capabilities include real-time image analysis for AI and QR scanning, live photo filters, concurrent camera support (beta), and programmable sensor configurations for zoom, flash, and brightness.

Tokens
36.7K
Snippets
102
Records
134
Agent score
75%

What's inside CamerAwesome

  1. Overview of CamerAwesome features

    master

    CamerAwesome is a highly customizable camera plugin for Flutter that provides a wide range of native camera capabilities for both Android and iOS. It allows developers to use a pre-built, high-quality interface or build a completely custom camera experience from scratch.

    Supported Native Features

    FeatureAndroidiOS
    Ask permissions
    Record video
    Multi camera
    Enable/disable audio
    Take photos
    Photo live filters
    Exposure level
    Broadcast live image stream
    Image analysis (barcode scan, etc.)
    Zoom
    Device flash support
    Auto focus
    Live switching camera
    Camera rotation stream
    Background auto stop
    Sensor type switching⛔️
    Enable/disable front camera mirroring
  2. Use CamerAwesome widgets for camera integration

    master

    CamerAwesome provides a suite of pre-built widgets designed to simplify camera integration. The primary entry point is the CameraAwesomeBuilder, which offers two distinct modes of operation:

    1. Standard UI: Use CameraAwesomeBuilder.awesome() to use the pre-configured CamerAwesome UI with minimal customization.
    2. Custom UI: Use CameraAwesomeBuilder.custom() (implied by context of building entirely custom UI) to build your own camera interface from scratch.

    Other available widgets include layout components, action buttons (flash, camera switch, aspect ratio, location, pause/resume), and specialized selectors (filters, camera modes, sensor types, zoom).

  3. How CameraState works and how to use it

    master

    CamerAwesome uses a state pattern to ensure you can only call methods available on the current camera state. The builder method in CameraAwesomeBuilder is called every time the camera switches states, allowing you to build a reactive UI.

    Camera States

    • PreparingCameraState: Camera is starting.
    • PhotoCameraState: Camera is ready to take a photo.
    • VideoCameraState: Camera is ready to take a video.
    • VideoRecordingCameraState: Camera is currently recording a video.
    • PreviewCameraState: Camera is in preview-only mode.
    • AnalysisCameraState: Camera is in analysis-only mode.

    Using the state.when() pattern

    To interact with the camera safely, use the .when() method on the provided CameraState to access state-specific methods:

    state.when(
        onAnalysisOnlyMode: (analysisCameraState) => analysisCameraState.startAnalysis(),
        onPhotoMode: (photoCameraState) => photoCameraState.takePhoto(),
        onVideoMode: (videoCameraState) => videoCameraState.startRecording(),
        onVideoRecordingMode: (videoRecordingCameraState) => videoRecordingCameraState.stopRecording(),
        onPreparingCamera: (preparingCameraState) => Loader(),
        onPreviewMode: (previewCameraState) => previewModeState.focus(),
    );
  4. Multi-camera limitations and platform differences

    master

    The concurrent camera feature (BETA) has several limitations:

    Platform Limits

    • Android: Maximum 2 cameras. Sensors used are typically one front and one back sensor.
    • iOS: Maximum 3 cameras.

    Functional Limitations

    • Sensor Settings: flashMode and aspectRatio only apply to the first (main) sensor.
    • Video Recording: Concurrent camera video recording is not yet supported.
    • Analysis Mode: Analysis mode with concurrent cameras is not yet supported.
    • Capture vs Preview: The PiP preview is a UI element. When you take a photo, CamerAwesome captures individual files for each sensor. It does not merge them into a single image; you are responsible for merging them manually if needed.
  5. Create a custom camera interface

    master

    If the built-in UI is insufficient, use CameraAwesomeBuilder.custom(). This provides a builder function that allows you to define your own UI. The camera preview will be rendered behind the content you provide in the builder.

    The builder follows the CameraLayoutBuilder signature: typedef CameraLayoutBuilder = Widget Function(CameraState cameraState, PreviewSize previewSize, Rect previewRect);

    CameraAwesomeBuilder.custom(
      saveConfig: SaveConfig.image(pathBuilder: _path()),
      builder: (state, previewSize, previewRect) {
        // create your interface here
      },
    )
  6. How to detect if a barcode is within a specific scan area

    master

    To determine if a detected barcode is within a user-defined scan area:

    1. Calculate the Scan Area: Define a Rect (e.g., centered in the previewRect).
    2. Convert Barcode Corners: Iterate through the detected Barcode objects. Use preview.convertFromImage() to convert the barcode's corner points from the AnalysisImage coordinate space to the Preview coordinate space.
    3. Create a Barcode Rect: Construct a Rect from the converted corner points.
    4. Check Intersection: Check if the center of the barcode Rect (or the intersection area) is contained within your defined scan area Rect.

    Note: For higher precision, instead of checking the center point, calculate the area of intersection between the barcode and the scan area and compare it against a threshold percentage.

  7. Choose the right CameraAwesomeBuilder constructor for your use case

    master

    Depending on your requirements, you can choose between different constructors for CameraAwesomeBuilder:

    • Full UI: Use CameraAwesomeBuilder.awesome() for a complete camera experience with built-in UI components (top/middle/bottom actions).
    • Custom UI: Use CameraAwesomeBuilder.custom() if the standard top/middle/bottom layout does not suit your needs. See Creating a custom UI for details.
    • Preview Only: Use CameraAwesomeBuilder.previewOnly() if you only want to display the camera preview without any photo or video capture capabilities.
    • Analysis Only: Use CameraAwesomeBuilder.analysisOnly() if you are only interested in image analysis. This constructor will not provide a camera preview behind your builder. This is useful for drawing custom filter effects or overlays based on analysis results.
  8. Understand the AwesomeCameraLayout structure

    master

    The AwesomeCameraLayout widget is the foundation for building camera interfaces in CamerAwesome. It divides the UI into three distinct functional areas:

    1. Top actions: Secondary controls like flash, aspect ratio, etc.
    2. Middle content: Additional elements such as filters or text indications.
    3. Bottom actions: Primary controls like the capture button or camera switching.

    CameraAwesomeBuilder provides a builder for each of these parts. If you pass null to any of these parameters, CamerAwesome provides default widgets:

    • topActions defaults to AwesomeTopActions(state: state).
    • middleContent defaults to a Column containing a Spacer, an AwesomeFilterWidget (if in CaptureMode.photo), a theme-colored divider, and an AwesomeCameraModeSelector.
    • bottomActions defaults to AwesomeBottomActions(state: state, onMediaTap: onMediaTap).

    The layout is implemented as a Column, where middleContent is wrapped in an Expanded widget to fill the available space.

    AwesomeCameraLayout({
        super.key,
        required this.state,
        OnMediaTap? onMediaTap,
        Widget? middleContent,
        Widget? topActions,
        Widget? bottomActions,
    }) 
  9. Draw overlays using Canvas transformations

    master

    To draw detected features (like face contours) correctly on top of the camera preview, you must account for coordinate transformations, especially on Android where the analysis image might not be mirrored like the preview.

    1. Get Transformation: Use img.getCanvasTransformation(preview) to obtain the necessary transformation.
    2. Apply to Canvas: In your CustomPainter.paint method, use canvas.save(), then canvas.applyTransformation(transformation, size), and finally canvas.restore() to ensure subsequent drawing operations are not affected.
    3. Coordinate Mapping: Use preview.convertFromImage(offset, img) to convert coordinates from the raw analysis image space to the actual screen/preview space.
    @override
    void paint(Canvas canvas, Size size) {
      if (canvasTransformation != null) {
        canvas.save();
        canvas.applyTransformation(canvasTransformation!, size);
      }
    
      // ... draw elements using converted coordinates ...
      // Example: position = preview!.convertFromImage(offset, model.img!);
    
      if (canvasTransformation != null) {
        canvas.restore();
      }
    }
  10. Understand CameraState lifecycle

    master

    The CameraState object is the primary way to manage the camera. The state transitions through several modes:

    • PreparingCameraState: Occurs when the app starts.
    • PhotoCameraState or VideoCameraState: Determined by your initialCaptureMode.
    • VideoRecordingCameraState: Entered when video recording starts.
    • VideoCameraState: Returned to when video recording stops.

    You can use state.when() to handle specific modes safely.

    state.when(
      onPhotoMode: (photoState) => photoState.start(),
      onVideoMode: (videoState) => videoState.start(),
      onVideoRecordingMode: (videoState) => videoState.pause(),
    );
  11. Customize UI areas with builders

    master

    The built-in UI is divided into three distinct areas that you can customize by providing builder functions to CameraAwesomeBuilder.awesome. You can return custom widgets or reuse built-in widgets (like AwesomeFlashButton or AwesomeFilterWidget) within these builders.

    • topActionsBuilder: Controls the top part of the UI.
    • middleContentBuilder: Controls the content area between the top and bottom actions.
    • bottomActionsBuilder: Controls the bottom action bar area.
    CameraAwesomeBuilder.awesome(
      topActionsBuilder: (state) => AwesomeTopActions(
        state: state,
        children: [ /* your widgets */ ],
      ),
      middleContentBuilder: (state) => Column(
        children: [ /* your widgets */ ],
      ),
      bottomActionsBuilder: (state) => AwesomeBottomActions(
        state: state,
        left: AwesomeFlashButton(state: state),
        right: AwesomeCameraSwitchButton(state: state),
      ),
    );