Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tempImage being null cause a fatal exception #144

Open
gmarizy opened this issue Feb 27, 2024 · 9 comments
Open

tempImage being null cause a fatal exception #144

gmarizy opened this issue Feb 27, 2024 · 9 comments
Assignees
Labels
need fix Issues that @chooyan-eng need to do something

Comments

@gmarizy
Copy link

gmarizy commented Feb 27, 2024

Version used: 1.0.2.

Stack trace:
Fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: Null check operator used on a null value
#00 pc 0x5d3ffb party.mojito (imageImageParser. [image_image_parser.dart:27]) (BuildId: b866ace14c967e51f7dae5b7c6ff4765)
#1 pc 0x5a10ab party.mojito (_parseFunc [crop.dart:751]) (BuildId: b866ace14c967e51f7dae5b7c6ff4765)
#2 pc 0x5a0f53 party.mojito (_parseFunc [crop.dart:748]) (BuildId: b866ace14c967e51f7dae5b7c6ff4765)
...

@chooyan-eng
Copy link
Owner

@gmarizy
Thank you for your feedback. It seems parsing the original image of Uint8List fails, but can you provide a minimum snippet that reproduces the issue?

@chooyan-eng chooyan-eng self-assigned this Feb 27, 2024
@chooyan-eng chooyan-eng added the need fix Issues that @chooyan-eng need to do something label Feb 27, 2024
@gmarizy
Copy link
Author

gmarizy commented Feb 27, 2024

It happened in production. Occurrence is not systematic, rather rare in fact. I tried a few things but didn't succeeded to reproduce it.

@chooyan-eng
Copy link
Owner

@gmarizy
Can you provide info at least about what argument of Crop is used, and the original image is possible?

@gmarizy
Copy link
Author

gmarizy commented Feb 27, 2024

I use a very UI-tweaked version of Crop (brace yourself):

class InteractiveCrop extends StatelessWidget {
  final Uint8List image;
  final double aspectRatio;
  final CropController controller;
  final ValueChanged<Uint8List> onCropped;
  final ValueChanged<CropStatus>? onStatusChanged;

  const InteractiveCrop({
    super.key,
    required this.image,
    this.aspectRatio = 9 / 16,
    required this.controller,
    required this.onCropped,
    this.onStatusChanged,
  });

  @override
  Widget build(BuildContext context) => LayoutBuilder(
        builder: (context, constraints) {
          final cropZone = _getCropZone(constraints.biggest);
          final roundedCropZone = RRect.fromRectAndRadius(
            cropZone,
            const Radius.circular(Dimens.radiusM),
          );

          return Stack(
            children: [
              Crop(
                initialRectBuilder: (viewportRect, imageRect) => cropZone,
                cornerDotBuilder: (_, __) => const SizedBox.shrink(),
                interactive: true,
                fixCropRect: true,
                maskColor: Colors.transparent,
                baseColor: Theme.of(context).colorScheme.background,
                controller: controller,
                image: image,
                onCropped: onCropped,
                onStatusChanged: onStatusChanged,
              ),
              IgnorePointer(child: _RevealOverlay(roundedCropZone)),
              IgnorePointer(
                child: Container(
                  margin:
                      EdgeInsets.only(left: cropZone.left, top: cropZone.top),
                  width: cropZone.width,
                  height: cropZone.height,
                  decoration: BoxDecoration(
                    border: Border.all(
                      color: Colors.white,
                      width: 4,
                    ),
                    borderRadius: roundedCornerBorderRadius,
                  ),
                ),
              )
            ],
          );
        },
      );

  Rect _getCropZone(Size size) {
    final rect = Rect.fromLTWH(
      0,
      0,
      size.width,
      size.height,
    );

    final maxWidth = rect.width * 2 / 3;
    final maxHeight = rect.height * 2 / 3;

    if (maxWidth / aspectRatio < maxHeight) {
      return Rect.fromCenter(
        center: rect.center,
        width: maxWidth,
        height: maxWidth / aspectRatio,
      );
    } else {
      return Rect.fromCenter(
        center: rect.center,
        width: maxHeight * aspectRatio,
        height: maxWidth,
      );
    }
  }
}

// https://www.flutterclutter.dev/flutter/tutorials/how-to-cut-a-hole-in-an-overlay/2020/510/
class _RevealOverlay extends StatelessWidget {
  final RRect _revealed;

  const _RevealOverlay(this._revealed);

  @override
  Widget build(BuildContext context) => ClipPath(
        clipper: _RevealClipper(_revealed),
        child: Container(
          color: MojitoColors.intenseDarkVeil,
        ),
      );
}

class _RevealClipper extends CustomClipper<Path> {
  const _RevealClipper(this._revealed);

  final RRect _revealed;

  @override
  Path getClip(Size size) => Path()
    ..addRect(Rect.fromLTWH(0, 0, size.width, size.height))
    ..addRRect(_revealed)
    ..fillType = PathFillType.evenOdd;

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => true;
}

I don't have the original image sadly; I use this lib to crop images before uploading them to my server.

@chooyan-eng
Copy link
Owner

@gmarizy Thanks! I'll try to reproduce with this code first.

@gmarizy
Copy link
Author

gmarizy commented Mar 3, 2024

@chooyan-eng I found a way to reproduce this error; when I try to crop an image from an .heic source on an Android device, this error is systematic.

@chooyan-eng
Copy link
Owner

@gmarizy Thanks! I'll try that.

@gmarizy
Copy link
Author

gmarizy commented Mar 16, 2024

@chooyan-eng Did you succeed to reproduce the bug with .heic on Android device ?

@Lamda303
Copy link

@gmarizy same problem occasionally occurs with jpg and png images too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
need fix Issues that @chooyan-eng need to do something
Projects
None yet
Development

No branches or pull requests

3 participants