yellowQ-software / yellowQ-Flutter-Image-Painter

Flutter package for painting on images
MIT License
106 stars 117 forks source link

Null Safety on exportImage #10

Closed ccc-dvansevenant closed 2 years ago

ccc-dvansevenant commented 3 years ago

Thanks for this library, and starting to migrate it to null safety.

I am using image_painter: ^1.0.0-nullsafety.0.

My project is set with:

environment:
  sdk: ">=2.12.0 <3.0.0"

As I was implementing image_painter in my project, I was having issues with exportImage.

It kept complaining about ByteData, and then buffer. Eventually I hit upon this combination:

  ///Generates [Uint8List] of the [ui.Image] generated by the [renderImage()] method.
  ///Can be converted to image file by writing as bytes.
  Future<Uint8List?> exportImage() async {
    ui.Image _image;
    if (widget.isSignature) {
      final _boundary = _repaintKey.currentContext!.findRenderObject()
          as RenderRepaintBoundary;
      _image = await _boundary.toImage(pixelRatio: 3);
    } else if (widget.byteArray != null && _paintHistory.isEmpty) {
      return widget.byteArray;
    } else {
      _image = await _renderImage();
    }
    final byteData = await (_image.toByteData(format: ui.ImageByteFormat.png) as FutureOr<ByteData?>);
    return byteData?.buffer.asUint8List();

Note the last 2 lines, specifically.

I don't know if it's correct or not, but thought I'd pass it along in case it helps.

I'm still learning, very slowly, so it's certainly possible this could be done better.

lively-bigyan commented 3 years ago

Thank you for opening up the issue and bringing it to my attention. I will definitely take a look at it.

lively-bigyan commented 3 years ago

I am not able to reproduce the issue. It would be much faster and easier for us to fix the issue if you could provide the following informations.

ccc-dvansevenant commented 3 years ago

Sorry for the delay. Thanks for the quick reply. Here's my discovery process. Might be a bit verbose, but I want to cover the bases in case I did something wrong.

Using Android Studio 4.2.2 (was 4.2.1 when this started) Flutter v2.2.3 (was 2.2.2) Mac OS X Catalina

So, add a null check:

imgFile.writeAsBytesSync(image!);

Running again:

E/flutter ( 6142): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: type 'Future<ByteData?>' is not a subtype of type 'FutureOr<ByteData>' in type cast
E/flutter ( 6142): #0      ImagePainterState.exportImage (package:image_painter/src/paint_over_image.dart:464:5)
E/flutter ( 6142): <asynchronous suspension>
E/flutter ( 6142): #1      _ImagePainterExampleState.saveImage (package:image_painter_null_safety_test/main.dart:57:30)
E/flutter ( 6142): <asynchronous suspension>
E/flutter ( 6142): 

Modifying paint_over_image.dart line 463-464 gets rid of that error:

final byteData = await (\_image.toByteData(format: ui.ImageByteFormat.png)  
as FutureOr<ByteData?>);

But introduces an error about buffer:

/usr/local/Caskroom/flutter/2.0.4/flutter/.pub-cache/hosted/pub.dartlang.org/image_painter-1.0.0-nullsafety.0/lib/src/paint_over_image.dart:465:21: Error: Property 'buffer' cannot be accessed on 'ByteData?' because it is potentially null.
 - 'ByteData' is from 'dart:typed_data'.
Try accessing using ?. instead.
    return byteData.buffer.asUint8List();
                    ^^^^^^

So, modifying 465, as suggested:

return byteData?.buffer.asUint8List();

Seems to make it all work without complaint. But, again, do not know if it is the right way.

dchrzanowski commented 2 years ago

Flutter 2.5.1, dart 2.14.2

@lively-bigyan

I'm working with this library at the moment and can confirm that I have the same issue as @ccc-dvansevenant. Can also confirm that changing the paint_over_image.dart file (line 464/465) from:

final byteData = await (_image.toByteData(format: ui.ImageByteFormat.png)
    as FutureOr<ByteData>);
return byteData.buffer.asUint8List();

To:

final byteData = await (_image.toByteData(format: ui.ImageByteFormat.png)
    as FutureOr<ByteData?>);
return byteData?.buffer.asUint8List();

Does fix the problem.

Should I create a PR or are you ok fixing this @lively-bigyan ?

lively-bigyan commented 2 years ago

@dchrzanowski Thank you for the tests and the solution. I am currently working on some new features of the package so I couldn't push the fixes sooner. I shall fix it today.

lively-bigyan commented 2 years ago

On second thought, I just realized that I had it fixed on 0.4.0. Have you guys tried that version? @dchrzanowski @ccc-dvansevenant

ccc-dvansevenant commented 2 years ago

On second thought, I just realized that I had it fixed on 0.4.0. Have you guys tried that version? @dchrzanowski @ccc-dvansevenant

I've had to set aside that part of my project for a while, so I haven't updated anything. I'll try to have a look soon. Thanks!

dchrzanowski commented 2 years ago

@lively-bigyan I did not realize that 0.4.0 was null safety ready. I'll check it out tomorrow morning so.

dchrzanowski commented 2 years ago

On second thought, I just realized that I had it fixed on 0.4.0. Have you guys tried that version? @dchrzanowski @ccc-dvansevenant

0.4.0 works like a charm! Thanks @lively-bigyan!

lively-bigyan commented 2 years ago

Not a problem. Glad it helped.