camera_cutout 0.1.0 copy "camera_cutout: ^0.1.0" to clipboard
camera_cutout: ^0.1.0 copied to clipboard

A Flutter plugin for reading camera cutout bounds, safe insets, and drawable shape geometry on Android and iOS.

Camera Cutout #

A Flutter plugin for reading the position and drawable shape of a device camera cutout on Android and iOS.

Features #

  • Returns cutout bounds in Flutter logical pixels relative to the application window.
  • Returns display-cutout safe insets and the current screen size.
  • Returns a drawable vector path when one is available.
  • Streams updated geometry after rotation and window-layout changes.
  • Distinguishes notches, hole punches, Dynamic Island, and unknown shapes.
  • Reports whether geometry is exact, estimated, or bounds-only.
  • Supports CocoaPods and Swift Package Manager.

Platform behavior #

Platform Behavior
Android 12+ Reads DisplayCutout.cutoutPath and serializes the OS path into Flutter coordinates.
Android 9–11 Reads DisplayCutout.boundingRects and safe insets.
Android 7–8 Returns isSupported: false without failing the application.
iOS Resolves the hardware identifier against a bundled device catalog and returns estimated notch or Dynamic Island geometry.

UIKit exposes safe areas but does not expose iPhone sensor-housing geometry. The iOS catalog covers iPhone X through iPhone 17, iPhone Air, iPhone 16e, and iPhone 17e. Known iPhones without a cutout, iPads, and iPods return a supported result with an empty cutout list. An unknown future iPhone returns isSupported: false so callers can distinguish missing catalog data from a device that has no cutout.

Requirements #

  • Flutter 3.38.0 or later
  • Dart 3.10.0 or later
  • Android API 24 or later
  • iOS 13.0 or later

Installation #

dependencies:
  camera_cutout: <latest_version>

Then run:

flutter pub get

Usage #

import 'dart:async';

import 'package:camera_cutout/camera_cutout.dart';

final cameraCutout = CameraCutout();
final info = await cameraCutout.getInfo();

for (final cutout in info.cutouts) {
  final bounds = cutout.bounds;
  final path = cutout.path?.toPath();
  final kind = cutout.kind;
  final accuracy = cutout.accuracy;
}

final subscription = cameraCutout.changes.listen((info) {
  for (final cutout in info.cutouts) {
    renderCutout(cutout.path?.toPath(), cutout.bounds);
  }
});

await subscription.cancel();

Drawing the shape #

CameraCutoutPath.toPath() creates a dart:ui Path in screen coordinates. Use the returned path directly in a full-window CustomPainter. When path is null, draw the supplied bounds as the fallback.

void paintCutout(Canvas canvas, CameraCutoutGeometry cutout) {
  final path = cutout.path?.toPath() ?? Path()..addOval(cutout.bounds);
  canvas.drawPath(
    path,
    Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2,
  );
}

Android edge-to-edge layout #

The plugin only reads window geometry and does not change host layout policy. An overlay that must line up with a cutout should let its activity render into the cutout area.

class MainActivity : FlutterActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            window.attributes = window.attributes.apply {
                layoutInDisplayCutoutMode =
                    WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
            }
        }
    }
}

The included example selects LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS where Android supports it and uses Flutter's edge-to-edge system UI mode.

API #

CameraCutout #

  • Future<CameraCutoutInfo> getInfo() reads the current geometry.
  • Stream<CameraCutoutInfo> get changes emits geometry after relevant native layout changes.

CameraCutoutInfo #

  • platform
  • deviceIdentifier
  • deviceModel
  • screenSize
  • devicePixelRatio
  • safeInsets
  • isSupported
  • cutouts
  • hasCutout
  • hasExactPath

CameraCutoutGeometry #

  • bounds
  • kind
  • accuracy
  • path
  • hasPath

iOS catalog maintenance #

The catalog is intentionally local and deterministic. Update it when Apple releases a new iPhone identifier, verify the display family against current Apple design resources or Simulator profiles, and add the identifier to the iOS catalog before publishing a new version.

Example #

The example application draws the cutout shape at its physical screen position with a repeating glow animation and displays the returned bounds and accuracy.

Camera Cutout example outlining the hole-punch camera on a Nothing A063 in portrait orientation

Android exact-path detection on a Nothing A063: the glow follows the physical hole-punch camera while the example reports the detected bounds and accuracy.

License #

MIT

2
likes
150
points
42
downloads

Documentation

API reference

Publisher

verified publishercodegrowers.tech

Weekly Downloads

A Flutter plugin for reading camera cutout bounds, safe insets, and drawable shape geometry on Android and iOS.

Homepage
Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on camera_cutout

Packages that implement camera_cutout