my_filter_camera 3.0.0 copy "my_filter_camera: ^3.0.0" to clipboard
my_filter_camera: ^3.0.0 copied to clipboard

This package lets you use the camera with advanced digital filters, apply real-time effects, and customize your camera experience easily.

GitHub CI Buy Me A Coffee PayPal Sponsor Support Me on Ko-fi

my_filter_camera #

A Flutter plugin for real-time camera filters, filtered photo and video capture, exposure control, torch control, and front/back camera switching on Android and iOS.

Platform and requirements #

Requirement Supported value
Flutter >=3.47.1
Dart >=3.13.1 <4.0.0
Android API 24+
iOS 15.0+
Web, desktop Not supported

Android uses CameraX 1.6.1, Media3, and GPUImage-compatible filters. iOS uses AVFoundation, Core Image, and AVAssetWriter without a third-party pod. Both CocoaPods and Swift Package Manager are supported.

Platform support #

Capability Android iOS
Live camera preview and 13 filters
Filtered JPEG capture
MP4 recording with optional audio
Pause and resume recording
Front/back camera and torch
Exposure, contrast, gamma, and RGB controls
Hardware zoom for preview, photos, and video
Tap focus and exposure-point metering
Preferred video quality with native fallback
Typed video recording state
Automatic app lifecycle handling
Filter-processed video recording

Camera-dependent controls such as torch and exposure are applied only when the active device supports them. The selected filter and color adjustments are written into both JPEG captures and recorded MP4 video.

Features #

  • Real-time filters in an Android or iOS PlatformView.
  • Capture the currently selected filter to a JPEG file.
  • Record filter-processed MP4 video, with optional microphone audio.
  • Pause, resume, and stop an active video recording.
  • Switch front/back cameras and control the torch.
  • Query the active camera zoom range and apply hardware zoom.
  • Focus or meter exposure at normalized points; opt into tap and pinch gestures.
  • Select a preferred recording quality with a safe native fallback.
  • Adjust exposure compensation, contrast, gamma, and RGB values.
  • Receive camera, torch, recording, zoom, exposure, and capture state through typed Dart APIs.
  • Automatically stop/resume the camera with the application lifecycle.

Installation #

Add the package to pubspec.yaml:

dependencies:
  my_filter_camera: ^3.0.0

Android permissions #

The plugin manifest declares camera and microphone permissions. Do not add legacy storage permissions: captured files use app-private storage and recordings use MediaStore.

If your application never records audio, remove the merged microphone permission in your application manifest:

<uses-permission
    android:name="android.permission.RECORD_AUDIO"
    tools:node="remove" />

When using tools:node, add xmlns:tools="http://schemas.android.com/tools" to the root <manifest> element.

iOS permissions #

Add usage descriptions to the consuming application's ios/Runner/Info.plist. iOS terminates applications that access these capabilities without the matching description:

<key>NSCameraUsageDescription</key>
<string>Use the camera to preview filters and capture photos and videos.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Use the microphone only when recording video with audio.</string>

NSMicrophoneUsageDescription is required only when the application calls startVideoRecording(enableAudio: true).

See the platform channel contract for native arguments, return types, events, and error codes.

Basic usage #

Import the package and create one controller for one camera screen:

import 'package:my_filter_camera/my_filter_camera.dart';

final controller = CameraViewController(
  facing: CameraFacing.back,
  ratio: Ratio.ratio_16_9,
  autoResume: true,
  videoQuality: CameraVideoQuality.fullHd,
);

Display the preview. CameraView starts the controller automatically and reports startup errors through errorBuilder:

CameraView(
  controller: controller,
  enablePinchToZoom: true,
  enableTapToFocus: true,
  onDetect: (data, args) {
    // Capture events sent by the native implementation.
  },
  errorBuilder: (context, error) {
    return Center(child: Text('Camera error: $error'));
  },
)

Dispose the controller when the owner of the controller is removed:

@override
void dispose() {
  controller.dispose();
  super.dispose();
}

If CameraView creates its own controller, it always releases that controller. For an injected controller, autoDispose: true (the default) lets the widget release it.

Start, stop, and camera state #

When using the controller without CameraView:

final granted = await controller.checkPermission();
if (granted) {
  await controller.start();
}

controller.isRunningState.addListener(() {
  debugPrint('running: ${controller.isRunning}');
});

await controller.stop();

Only one native camera session should be active at a time. Stop or dispose the current controller before creating a camera screen with different settings.

Filters #

Filter type

await controller.updateFilter(
  filterType: PluginFilterEnum.GRAYSCALE.code,
);

final samples = await controller.applyImageSample();

PluginFilterEnum retains its uppercase 1.x names for source compatibility.

Capture an image #

Capture image

final XFile image = await controller.capture();
debugPrint(image.path);

Images are written to an app-private Images directory. No storage runtime permission is required.

Record video #

Record without audio:

await controller.startVideoRecording();
await controller.pauseVideoRecording();
await controller.resumeVideoRecording();
final XFile video = await controller.stopVideoRecording();

Build recording controls from typed state instead of maintaining a duplicate boolean in the application:

controller.recordingState.addListener(() {
  switch (controller.recordingState.value) {
    case CameraRecordingState.idle:
      // Show the record button.
    case CameraRecordingState.starting:
    case CameraRecordingState.stopping:
      // Show progress and temporarily disable controls.
    case CameraRecordingState.recording:
      // Show pause and stop.
    case CameraRecordingState.paused:
      // Show resume and stop.
  }
});

Record with audio (Android and iOS request microphone permission when needed):

await controller.startVideoRecording(enableAudio: true);
final XFile video = await controller.stopVideoRecording();

The returned MP4 is written to the app-specific Videos directory using a unique filename. Android also creates a MediaStore recording. On iOS, pause/resume records filtered segments and merges them when recording stops.

The filter visible in the preview is baked into the video. Calling updateFilter, adjustContrast, adjustGamma, or adjustRGB during recording applies the new values to subsequent frames without restarting the recording.

Camera controls #

await controller.switchCamera();

if (controller.hasTorch) {
  await controller.setTorch(TorchState.on);
}

final camera = controller.args.value!;
final appliedExposure = await controller.setExposureOffset(2.0);
final zoom = await controller.setZoomLevel(2.0);
final focused = await controller.setFocusPoint(const Offset(0.5, 0.5));
final metered = await controller.setExposurePoint(const Offset(0.5, 0.5));
await controller.resetFocusAndExposure();
final contrast = await controller.adjustContrast(value: 1.2);
final gamma = await controller.adjustGamma(value: 0.9);
final rgb = await controller.adjustRGB(red: 1, green: 0.95, blue: 0.9);

The exposure value is clamped from camera.minExposureOffset to camera.maxExposureOffset. Check supportsExposureOffset, supportsFocusPoint, and supportsExposurePoint before displaying the matching control. Focus and exposure points use normalized preview coordinates: top-left is Offset.zero, bottom-right is Offset(1, 1). Zoom is also clamped, so applications can build a slider directly from controller.minZoomLevel to controller.maxZoomLevel. Listen to controller.zoomLevelState when the UI needs the latest applied value. Hardware zoom affects the preview, captured JPEG, and recorded MP4 together.

enableTapToFocus meters focus and exposure together. Gesture errors can be observed with CameraView.onCameraControlError. Both gestures default to false, so they do not intercept touches in existing applications.

Video quality #

Choose lowest, sd, hd, fullHd, ultraHd, or highest when constructing the controller. This is a preference rather than a guarantee: unsupported qualities fall back to a compatible native CameraX or AVFoundation setting. The setting is applied the next time the camera starts.

Events #

controller.faces.listen((CameraData data) {
  debugPrint('captured path: ${data.faceImage}');
});

controller.torchState.addListener(() {
  debugPrint('torch: ${controller.torchState.value}');
});

controller.cameraRunningResponseStream.listen((event) {
  debugPrint('running: ${event.isCameraRunning}');
});

Delete plugin-created media #

removeDir() is destructive. It deletes the plugin's app-private Images and Videos directories. Android also deletes MediaStore videos whose display name starts with CameraX-recording-:

await controller.removeDir();

Error handling #

Native failures are returned as PlatformException; calls after dispose() throw StateError.

try {
  await controller.start();
} on PlatformException catch (error) {
  debugPrint('${error.code}: ${error.message}');
}

See MIGRATION.md when upgrading from 1.x, SECURITY.md for privacy guidance, and OPERATIONS.md for validation/release commands.

Contribute #

Issues and pull requests are welcome at GitHub. For project questions, contact Thao Doan or Duc Nguyen.

5
likes
160
points
185
downloads
screenshot

Documentation

API reference

Publisher

verified publisherwongcoupon.com

Weekly Downloads

This package lets you use the camera with advanced digital filters, apply real-time effects, and customize your camera experience easily.

Repository (GitHub)
View/report issues

Topics

#camera #photo-filters #real-time-effects #photography #media

Funding

Consider supporting this project:

github.com
www.buymeacoffee.com

License

MIT (license)

Dependencies

cross_file, flutter

More

Packages that depend on my_filter_camera

Packages that implement my_filter_camera