Open
Description
Steps to reproduce
- Navigate to image crop page through GoRouter with a local image path parameter
- Load image using
ExtendedImage.file
withExtendedImageMode.editor
- Set custom
CircleEditorCropLayerPainter
ascropLayerPainter
- Page loads and triggers assertion error
Expected results
The image crop page should display normally, allowing users to perform circular cropping operations without any rendering assertion errors.
Actual results
The application throws the following assertion error:
Code sample
Code sample
import 'dart:io';
import 'dart:typed_data';
import 'package:extended_image/extended_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:image_editor/image_editor.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
class ImageCropPage extends StatefulWidget {
const ImageCropPage({super.key, required this.imagePath});
final String imagePath;
@override
State<ImageCropPage> createState() => _ImageCropPageState();
}
final GlobalKey<ExtendedImageEditorState> editorKey =
GlobalKey<ExtendedImageEditorState>();
class _ImageCropPageState extends State<ImageCropPage> {
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: NavigationBarView(
title: t.utility.cropImage,
trailing: PureButton(
padding: EdgeInsets.only(right: 15.w),
onPressed: _cropImage,
child: Assets.setting.cropConfirm.image(width: 36.w, height: 36.w),
),
),
child: ExtendedImage.file(
File(widget.imagePath),
fit: BoxFit.contain,
mode: ExtendedImageMode.editor,
enableLoadState: true,
cacheRawData: true,
extendedImageEditorKey: editorKey,
initEditorConfigHandler: (state) {
return EditorConfig(
maxScale: 6.0,
cropRectPadding: const EdgeInsets.all(20.0),
hitTestSize: 20.0,
cropAspectRatio: CropAspectRatios.ratio1_1,
cropLayerPainter: const CircleEditorCropLayerPainter(),
);
},
),
);
}
}
class CircleEditorCropLayerPainter extends EditorCropLayerPainter {
const CircleEditorCropLayerPainter();
@override
void paint(
Canvas canvas,
Size size,
ExtendedImageCropLayerPainter painter,
Rect rect,
) {
final Rect cropRect = painter.cropRect;
final Paint paint = Paint()..color = painter.maskColor;
final Path mask = Path()
..addOval(cropRect)
..addRect(Rect.fromLTWH(0, 0, size.width, size.height))
..fillType = PathFillType.evenOdd;
canvas.saveLayer(Rect.fromLTWH(0, 0, size.width, size.height), Paint());
canvas.drawPath(mask, paint);
canvas.restore();
final Paint borderPaint = Paint()
..color = Colors.white
..style = PaintingStyle.stroke
..strokeWidth = 2.0;
canvas.drawOval(cropRect, borderPaint);
}
}
Screenshots or Video
Screenshots/videos would be helpful to demonstrate the issue.
Logs
Logs
════════ Exception caught by scheduler library ═════════════════════════════════
The following assertion was thrown during a scheduler callback:
'package:flutter/src/rendering/object.dart': Failed assertion: line 1191 pos 20: 'node.isRepaintBoundary': is not true.
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=2_bug.yml
When the exception was thrown, this was the stack:
#2 PipelineOwner.flushPaint (package:flutter/src/rendering/object.dart:1191:20)
object.dart:1191
#3 PipelineOwner.flushPaint (package:flutter/src/rendering/object.dart:1203:15)
object.dart:1203
#4 RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:611:23)
binding.dart:611
#5 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:1178:13)
binding.dart:1178
#6 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:475:5)
binding.dart:475
#7 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1397:15)
binding.dart:1397
#8 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1318:9)
binding.dart:1318
#9 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1176:5)
binding.dart:1176
#10 _invoke (dart:ui/hooks.dart:312:13)
hooks.dart:312
#11 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:427:5)
platform_dispatcher.dart:427
#12 _drawFrame (dart:ui/hooks.dart:283:31)
hooks.dart:283
(elided 2 frames from class _AssertionError)
Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.27.4, on macOS 15.3.2 24D81 darwin-arm64, locale zh-Hans-CN)
[!] Android toolchain - develop for Android devices (Android SDK version 35.0.1)
✗ Android license status unknown.
Run `flutter doctor --android-licenses` to accept the SDK licenses.
See https://flutter.dev/to/macos-android-setup for more details.
[✓] Xcode - develop for iOS and macOS (Xcode 16.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2024.3)
[✓] IntelliJ IDEA Ultimate Edition (version 2025.1.2)
[✓] VS Code (version 1.100.3)
[!] Proxy Configuration
! NO_PROXY is not set
[✓] Connected device (7 available)
[✓] Network resources
! Doctor found issues in 2 categories.