iris_camera 1.0.2
iris_camera: ^1.0.2 copied to clipboard
AVFoundation-powered camera toolkit with preview, lens control, and still capture APIs.
iris_camera #
iOS-first camera toolkit for Flutter. iris_camera exposes live preview widgets, structured lens descriptors, lens switching, and still-photo capture powered by AVFoundation β all through a single Dart API.
The plugin focuses on real hardware parity: it shares one AVCaptureSession between preview and capture so you always see exactly what the sensor sees when you trigger a shot, and it surfaces precise metadata (position, category, field of view, focus capability) for every selectable lens.
Platform coverage: only iOS is supported right now. Android and web implementations are planned for v2.0.0, but at the moment the plugin will no-op on other platforms.
Features #
- π Lens discovery β enumerate every physical lens that AVFoundation exposes (wide, ultra-wide, telephoto, dual/triple arrays, Continuity cameras, etc.).
- π Hardware switching β swap the active sensor with a single
switchLenscall; the plugin reconfigures the capture session for you and returns the selected descriptor. - πΌοΈ Shared preview widget β
IrisCameraPreviewrenders the nativeAVCaptureVideoPreviewLayervia aUiKitView, so the Flutter UI always shows what the active sensor sees β flip onenableTapToFocusandshowFocusIndicatorfor built-in gestures and overlays (customizable viaFocusIndicatorStyle). - πΈ Still capture β
capturePhoto()grabs a high-resolution JPEG from the same session, with flash mode plus manual exposure/ISO controls viaPhotoCaptureOptions. - π― Manual focus & zoom β call
setFocus()to drive tap-to-focus points or custom lens positions, andsetZoom()to animate digital zoom factors. - βͺ White balance overrides β
setWhiteBalance()accepts temperature/tint overrides or reverts to auto when omitted. - β οΈ Structured errors β
CameraLensSwitcherExceptionwraps native error codes/messages so your app can react consistently to permission or hardware failures.
Installation #
flutter pub add iris_camera
import 'package:iris_camera/iris_camera.dart';
final camera = IrisCamera();
final lenses = await camera.listAvailableLenses();
await camera.switchLens(CameraLensCategory.ultraWide);
final photo = await camera.capturePhoto(
options: const PhotoCaptureOptions(flashMode: PhotoFlashMode.auto),
);
Use the provided IrisCameraPreview widget to show the live feed:
IrisCameraPreview(
aspectRatio: 3 / 2,
borderRadius: const BorderRadius.all(Radius.circular(16)),
enableTapToFocus: true,
onTapFocus: (point) => camera.setFocus(point: point),
showFocusIndicator: true,
focusIndicatorStyle: const FocusIndicatorStyle(color: Colors.amber),
)
The full demo app is in example/lib/main.dart.
iOS Setup #
Add the camera usage string to your Info.plist:
<key>NSCameraUsageDescription</key>
<string>This app needs the camera to capture photos.</string>
Nothing else is required; the plugin automatically requests permission the first time you call switchLens or capturePhoto.
Front-facing lenses are currently filtered out of
listAvailableLenses. The shared preview/capture session mirrors the native output, so supporting front cameras would require a dedicated mirrored preview pipeline to avoid confusing users with flipped feeds. This is tracked for a future release; for now we only expose lenses we can render authentically.
Dart API Surface #
| API | Description | Key parameters |
|---|---|---|
Future<List<CameraLensDescriptor>> listAvailableLenses() |
Enumerate available lenses (back-facing only for now). | β |
Future<CameraLensDescriptor> switchLens(CameraLensCategory category) |
Reconfigure the session to the requested category (wide/ultraWide/telephoto/dual/triple/continuity/trueDepth). | category |
Future<Uint8List> capturePhoto({PhotoCaptureOptions options}) |
Capture a still JPEG from the active sensor. | PhotoCaptureOptions (see below) |
Future<void> setFocus({Offset? point, double? lensPosition}) |
Drive tap-to-focus or manual lens position. | point in 0β1 normalized preview coords, or lensPosition 0β1 |
Future<void> setZoom(double zoomFactor) |
Apply digital zoom within the active formatβs supported range. | zoomFactor |
Future<void> setWhiteBalance({double? temperature, double? tint}) |
Override white balance or revert to auto when omitted. | temperature, tint |
CameraLensDescriptorexposesid,name,position,category, optionalfocalLength,fieldOfView, andsupportsFocusto indicate whether tap/manual focus is available for that lens.PhotoCaptureOptionssupports:flashMode(auto,on,off)exposureDuration(Durationin microseconds; longer values enable long exposures, clamped to the device range)iso(double; clamped to the device range)
- Errors throw
CameraLensSwitcherException(code,message,details).
β οΈ Platform support: only iOS is implemented right now; Android/Web will no-op until v2 adds those backends.
#
Widgets #
| Widget | Description |
|---|---|
IrisCameraPreview |
Embeds the AVCaptureVideoPreviewLayer via UiKitView with built-in tap-to-focus + optional overlays (tweak via FocusIndicatorStyle or FocusIndicatorController). |
Example Interaction Flow #
final lenses = await camera.listAvailableLenses();
final ultraWide = lenses.firstWhere(
(lens) => lens.category == CameraLensCategory.ultraWide,
orElse: () => lenses.first,
);
try {
await camera.switchLens(ultraWide.category);
final photoBytes = await camera.capturePhoto();
// Save photoBytes to disk or upload.
// Tap-to-focus at the center of the preview.
await camera.setFocus(point: const Offset(0.5, 0.5));
} on CameraLensSwitcherException catch (error) {
debugPrint('Camera error: ${error.code} -> ${error.message}');
}
Tap-to-focus gestures and the indicator overlay are baked into the preview:
final focusController = FocusIndicatorController();
IrisCameraPreview(
enableTapToFocus: true,
onTapFocus: (point) => camera.setFocus(point: point),
showFocusIndicator: true,
focusIndicatorController: focusController, // Optional override.
focusIndicatorStyle: const FocusIndicatorStyle(
color: Colors.greenAccent,
size: 72,
),
);
Roadmap #
- Finalize front-camera support (mirrored preview + capture pipeline).
- Android implementation (likely CameraX) with the same Dart API.
- Video capture hooks built on the shared session.
- Publish v1.0 once cross-platform parity is reached, then revisit v2 for Android.
License #
MIT β see LICENSE.