How to customize google maps marker icon in Flutter How to customize google maps marker icon in Flutter flutter flutter

How to customize google maps marker icon in Flutter


enter image description here

To achieve the above styling fallow steps bellow:

  1. Import packages
import 'dart:async';import 'dart:ui' as ui;import 'dart:typed_data';import 'dart:io';import 'package:flutter/material.dart';
  1. (Optional) Add a helper function to get image by the path
Future<ui.Image> getImageFromPath(String imagePath) async {    File imageFile = File(imagePath);    Uint8List imageBytes = imageFile.readAsBytesSync();    final Completer<ui.Image> completer = new Completer();    ui.decodeImageFromList(imageBytes, (ui.Image img) {      return completer.complete(img);    });    return completer.future;}
  1. Add function getMarkerIcon() returning BitmapDescriptor. This is a replacement for your function getBytesFromCanvas()
Future<BitmapDescriptor> getMarkerIcon(String imagePath, Size size) async {    final ui.PictureRecorder pictureRecorder = ui.PictureRecorder();    final Canvas canvas = Canvas(pictureRecorder);    final Radius radius = Radius.circular(size.width / 2);    final Paint tagPaint = Paint()..color = Colors.blue;    final double tagWidth = 40.0;    final Paint shadowPaint = Paint()..color = Colors.blue.withAlpha(100);    final double shadowWidth = 15.0;    final Paint borderPaint = Paint()..color = Colors.white;    final double borderWidth = 3.0;    final double imageOffset = shadowWidth + borderWidth;    // Add shadow circle    canvas.drawRRect(        RRect.fromRectAndCorners(          Rect.fromLTWH(              0.0,              0.0,              size.width,              size.height          ),          topLeft: radius,          topRight: radius,          bottomLeft: radius,          bottomRight: radius,        ),        shadowPaint);    // Add border circle    canvas.drawRRect(        RRect.fromRectAndCorners(          Rect.fromLTWH(              shadowWidth,              shadowWidth,              size.width - (shadowWidth * 2),              size.height - (shadowWidth * 2)          ),          topLeft: radius,          topRight: radius,          bottomLeft: radius,          bottomRight: radius,        ),        borderPaint);    // Add tag circle    canvas.drawRRect(        RRect.fromRectAndCorners(          Rect.fromLTWH(              size.width - tagWidth,              0.0,              tagWidth,              tagWidth          ),          topLeft: radius,          topRight: radius,          bottomLeft: radius,          bottomRight: radius,        ),        tagPaint);    // Add tag text    TextPainter textPainter = TextPainter(textDirection: TextDirection.ltr);    textPainter.text = TextSpan(      text: '1',      style: TextStyle(fontSize: 20.0, color: Colors.white),    );    textPainter.layout();    textPainter.paint(        canvas,        Offset(            size.width - tagWidth / 2 - textPainter.width / 2,            tagWidth / 2 - textPainter.height / 2        )    );    // Oval for the image    Rect oval = Rect.fromLTWH(        imageOffset,        imageOffset,        size.width - (imageOffset * 2),        size.height - (imageOffset * 2)    );    // Add path for oval image    canvas.clipPath(Path()      ..addOval(oval));    // Add image    ui.Image image = await getImageFromPath(imagePath); // Alternatively use your own method to get the image    paintImage(canvas: canvas, image: image, rect: oval, fit: BoxFit.fitWidth);    // Convert canvas to image    final ui.Image markerAsImage = await pictureRecorder.endRecording().toImage(        size.width.toInt(),        size.height.toInt()    );    // Convert image to bytes    final ByteData byteData = await markerAsImage.toByteData(format: ui.ImageByteFormat.png);    final Uint8List uint8List = byteData.buffer.asUint8List();    return BitmapDescriptor.fromBytes(uint8List);}
  1. Use it like so
final Marker marker = Marker(      icon: await getMarkerIcon("path/to/your/image.png", Size(150.0, 150.0)));

Note:The tag with a number is positioned 'loosely' for the demo purpose - you might need to style it differently so it would expand with the content.


  1. uses image package, https://pub.dev/packages/image, as im
  2. download imageFile f = await _downloadFile(url, "border");im.Image img = im.decodeImage(f.readAsBytesSync());
  3. use drawString() to write number on it
  4. BitmapDescriptor.fromBytes(im.encodePng(img))

static var httpClient = new HttpClient();

Future<File> _downloadFile(String url, String filename) async {    var request = await httpClient.getUrl(Uri.parse(url));    var response = await request.close();    var bytes = await consolidateHttpClientResponseBytes(response);    String dir = (await getApplicationDocumentsDirectory()).path;    File file = new File('$dir/$filename');    await file.writeAsBytes(bytes);    return file;  }