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

[Google_maps]After change BitmapDescriptor.fromBytes to BitmapDescriptor.bytes app crash #149183

Closed
PrzemyslawPluszowy opened this issue May 28, 2024 · 15 comments · Fixed by flutter/packages#6832
Labels
c: regression It was better in the past than it is now p: maps Google Maps plugin P1 High-priority issues at the top of the work list package flutter/packages repository. See also p: labels. team-ecosystem Owned by Ecosystem team triaged-ecosystem Triaged by Ecosystem team

Comments

@PrzemyslawPluszowy
Copy link

PrzemyslawPluszowy commented May 28, 2024

Steps to reproduce

image
this func work good but if i change to BitmapDescriptor.bytes(imageToBytesUint8List);
i have this error:
image

What is wrong?

Expected results

Need find solution for this error

Actual results


E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): Failed to handle method call
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): java.lang.IllegalArgumentException: Cannot interpret [bytes, {bitmapScaling=auto, byteData=[B@420caa1, imagePixelRatio=1.0}] as BitmapDescriptor
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): 	at io.flutter.plugins.googlemaps.Convert.toBitmapDescriptor(Convert.java:71)
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): 	at io.flutter.plugins.googlemaps.Convert.interpretMarkerOptions(Convert.java:452)
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): 	at io.flutter.plugins.googlemaps.MarkersController.addMarker(MarkersController.java:195)
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): 	at io.flutter.plugins.googlemaps.MarkersController.addMarkers(MarkersController.java:41)
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): 	at io.flutter.plugins.googlemaps.GoogleMapController.onMethodCall(GoogleMapController.java:385)
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): 	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:267)
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): 	at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:292)
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): 	at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:319)
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): 	at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): 	at android.os.Handler.handleCallback(Handler.java:900)
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): 	at android.os.Handler.dispatchMessage(Handler.java:103)
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): 	at android.os.Looper.loop(Looper.java:219)
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): 	at android.app.ActivityThread.main(ActivityThread.java:8668)
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): 	at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
E/MethodChannel#plugins.flutter.dev/google_maps_android_3(18423): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)

Code sample

Code sample
 static generateCustomMarkersIconFromPath(String? path) async {
    try {
      if (path == null || path.isEmpty) {
        return BitmapDescriptor.defaultMarker;
      }
      Uint8List bytes = File(path).readAsBytesSync();
      bytes = (_resizeImage(bytes, 140, 140))!;

      ui.Image image = await _convertImageFromUint8ListToCanvasImage(bytes);
      final generatedImage = await _drawCanvas(image);
      final ByteData? imageToBytes =
          await generatedImage.toByteData(format: ui.ImageByteFormat.png);
      if (imageToBytes == null) {
        return BitmapDescriptor.defaultMarker;
      }
      final Uint8List imageToBytesUint8List = imageToBytes.buffer.asUint8List();
      return BitmapDescriptor.bytes(imageToBytesUint8List);
    } catch (e) {
      return BitmapDescriptor.defaultMarker;
    }
  }

  static Future<ui.Image> _drawCanvas(ui.Image image) async {
    ui.PictureRecorder recorder = ui.PictureRecorder();
    Canvas canvasRecord = Canvas(recorder);
    PinCanavasDraw pinCanvasDraw = PinCanavasDraw(image: image);
    pinCanvasDraw.paint(canvasRecord, const Size(200, 200));
    var genratedImage = await recorder.endRecording().toImage(200, 200);
    return genratedImage;
  }

  static Uint8List? _resizeImage(Uint8List data, width, height) {
    Uint8List? resizedData = data;
    ui_image.Image? img = ui_image.decodeImage(data);
    ui_image.Image resized =
        ui_image.copyResize(img!, width: width, height: height);
    resizedData = Uint8List.fromList(ui_image.encodePng(resized));
    return resizedData;
  }

  static Future<ui.Image> _convertImageFromUint8ListToCanvasImage(
      Uint8List img) async {
    final Completer<ui.Image> completer = Completer();
    ui.decodeImageFromList(img, (ui.Image img) {
      return completer.complete(img);
    });
    return completer.future;
  }
}

class PinCanavasDraw extends CustomPainter {
  PinCanavasDraw({
    required this.image,
  });

  ui.Image image;

  @override
  void paint(Canvas canvas, Size size) async {
    Paint paint1 = Paint()
      ..color = const Color.fromARGB(163, 0, 0, 0).withOpacity(0.8)
      ..strokeWidth = 1
      ..style = PaintingStyle.fill;
    canvas.drawRect(const Rect.fromLTWH(23, 23, 154, 154), paint1);
    Path pathPin = Path()
      ..moveTo(100, 200)
      ..lineTo(80, 170)
      ..lineTo(120, 170)
      ..close();
    Path pathShadow = Path()..addRect(const Rect.fromLTWH(23, 23, 154, 154));
    canvas.drawPath(pathPin, paint1);
    canvas.drawShadow(pathShadow, const Color.fromARGB(255, 0, 0, 0), 3, false);

    canvas.drawImage(image, const Offset(30, 30), Paint());
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}

Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
[Paste your output here]
@GrzywN
Copy link

GrzywN commented May 28, 2024

Having the same problem after migration, pls help :D

@PrzemyslawPluszowy PrzemyslawPluszowy changed the title After change BitmapDescriptor.fromBytes to BitmapDescriptor.bytes app crash [Google_maps]After change BitmapDescriptor.fromBytes to BitmapDescriptor.bytes app crash May 28, 2024
@darshankawar darshankawar added the in triage Presently being triaged by the triage team label May 29, 2024
@darshankawar
Copy link
Member

@PrzemyslawPluszowy Can you provide us a runnable reproducible code sample in properly formatted text so that we can directly use it and verify at our end ? Providing code screenshot isn't much helpful.

@darshankawar darshankawar added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label May 29, 2024
@PrzemyslawPluszowy

This comment was marked as outdated.

@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label May 29, 2024
@PrzemyslawPluszowy
Copy link
Author

another error after migration to flutter maps 2.6.1 in another project
when i'm back to .fromAssetImage all work fine

static Future<BitmapDescriptor> _createIcon(MapPinType type) async {
    return await BitmapDescriptor.asset(
      const ImageConfiguration(
        devicePixelRatio: 2.5,
        size: Size(28, 28),
      ),
      type.getPathIcon(),
    );
  }
}

enum MapPinType {
  accident,
  towing,
  delivery;

  String getPathIcon() {
    switch (this) {
      case MapPinType.accident:
        return Assets.images.iconMapCrashPng.path;
      case MapPinType.towing:
        return Assets.images.garageMapIcon.path;
      case MapPinType.delivery:
        return Assets.images.iconMapHome.path;
    }
  }
}

image

@darshankawar
Copy link
Member

static generateCustomMarkersIconFromPath(String? path) async {

@PrzemyslawPluszowy How are you calling this method ? Can you provide us complete code (ex: main.dart) so that we can simply copy paste and verify this further ?

another error after migration to flutter maps 2.6.1 in another project

What version you were on earlier before upgrading to 2.6.1 ?
Also, this issue I was able to replicate with the help of another issue.

@darshankawar darshankawar added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label May 29, 2024
@PrzemyslawPluszowy
Copy link
Author

PrzemyslawPluszowy commented May 29, 2024

this is the same issue #149226 (comment)
Version 2.6.0, but I think the problem is with it when I upgraded Flutter to the newest version and ide show me deprecated

@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label May 29, 2024
@stuartmorgan
Copy link
Contributor

This is an unintended effect of the way the federated change to add the new formats was rolled out. The new formats won't be supported until flutter/packages#6826 lands.

@jokerttu Could you do a new PR ASAP to remove the deprecation notice? We can re-add it after the implementation PRs have landed.

@stuartmorgan stuartmorgan added c: regression It was better in the past than it is now p: maps Google Maps plugin package flutter/packages repository. See also p: labels. team-ecosystem Owned by Ecosystem team P1 High-priority issues at the top of the work list triaged-ecosystem Triaged by Ecosystem team and removed in triage Presently being triaged by the triage team labels May 29, 2024
@jokerttu
Copy link

This is an unintended effect of the way the federated change to add the new formats was rolled out. The new formats won't be supported until flutter/packages#6826 lands.

@jokerttu Could you do a new PR ASAP to remove the deprecation notice? We can re-add it after the implementation PRs have landed.

@stuartmorgan PR available here: flutter/packages#6832
The documentation still encourages to use new methods, even though their platform implementations are not yet available.
Should those be reverted as well, before flutter/packages#6826 lands.

@stuartmorgan
Copy link
Contributor

Re-opening as the crash will still happen if people use the new methods; removing the deprecation should just reduce the chances of people starting to use them before the implementation lands.

Should those be reverted as well, before flutter/packages#6826 lands.

Let's see how quickly the implementations land; not actively pushing people to the not-yet-supported versions should help a lot.

(In retrospect, yes, we should have added the class without public constructors first, then added support for them, then added the constructors and the deprecations.)

@MMoarales
Copy link

Same problem here, someone has any solution for this ?

@stuartmorgan
Copy link
Contributor

The solution is not to use the new constructors until flutter/packages#6826 lands.

@MMoarales
Copy link

Ok, got it, thank you!!!

arc-yong pushed a commit to Arctuition/packages-arc that referenced this issue Jun 14, 2024
)

Undeprecate BitmapDescriptor.fromAssetImage and BitmapDescriptor.fromBytes

* Undeprecates `BitmapDescriptor.fromAssetImage`.
* Undeprecates `BitmapDescriptor.fromBytes`.
* Fixes issues with deprecation in version 2.7.0.

The new formats won't be supported until flutter#6826 lands.
Deprecation notices can be re-added after the implementation PRs have landed.

Fixes: flutter/flutter#149183
@SkimoBen
Copy link

One thing I've noticed when using BitmapDescriptor.fromAssetImage() is that the marker sizing ends up being totally different on android Vs. iOS / chrome. So like everyone else has mentioned, using the other deprecated method return BitmapDescriptor.fromBytes(resizedData); Seems like the best solution currently.

It will be really awesome if BitmapDescriptor.asset() just works soon.

@jokerttu
Copy link

jokerttu commented Jun 20, 2024

flutter/packages#6826 is now landed and new methods, BitmapDescriptor.asset() and BitmapDescriptor.bytes() are implemented for each platform, and can be used after using after plugin versions are updated to latest.
Latest version of google_maps_flutter 2.7.0 now also exposes new AssetMapBitmap and BytesMapBitmap classes.
See example to see how to use these new methods.

Copy link

github-actions bot commented Jul 4, 2024

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 4, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
c: regression It was better in the past than it is now p: maps Google Maps plugin P1 High-priority issues at the top of the work list package flutter/packages repository. See also p: labels. team-ecosystem Owned by Ecosystem team triaged-ecosystem Triaged by Ecosystem team
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants