Is it possible to use SVG paths to create a marker with the google_maps_flutter plugin? I know you can use .png
files by using:
icon: BitmapDescriptor.fromAsset("images/myFile.png")
How about SVG paths?
Thanks
This can be achieved using the flutter_svg package.
import 'dart:ui' as ui; // imported as ui to prevent conflict between ui.Image and the Image widget
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
Future<BitmapDescriptor> _bitmapDescriptorFromSvgAsset(BuildContext context, String assetName) async {
// Read SVG file as String
String svgString = await DefaultAssetBundle.of(context).loadString(assetName);
// Create DrawableRoot from SVG String
DrawableRoot svgDrawableRoot = await svg.fromSvgString(svgString, null);
// toPicture() and toImage() don't seem to be pixel ratio aware, so we calculate the actual sizes here
MediaQueryData queryData = MediaQuery.of(context);
double devicePixelRatio = queryData.devicePixelRatio;
double width = 32 * devicePixelRatio; // where 32 is your SVG's original width
double height = 32 * devicePixelRatio; // same thing
// Convert to ui.Picture
ui.Picture picture = svgDrawableRoot.toPicture(size: Size(width, height));
// Convert to ui.Image. toImage() takes width and height as parameters
// you need to find the best size to suit your needs and take into account the
// screen DPI
ui.Image image = await picture.toImage(width, height);
ByteData bytes = await image.toByteData(format: ui.ImageByteFormat.png);
return BitmapDescriptor.fromBytes(bytes.buffer.asUint8List());
}
You can then use the BitmapDescriptor to create a Marker as usual:
BitmapDescriptor bitmapDescriptor = await _bitmapDescriptorFromSvgAsset(context, 'assets/images/someimage.svg');
Marker marker = Marker(markerId: MarkerId('someId'), icon: bitmapDescriptor, position: LatLng(someLatitude, someLongitude));
Here are few options:
getBitmapDescriptorFromSvgAsset
- svg from assets getBitmapDescriptorFromSvgString
- svg as string from db/remote/whateverclass BitmapDescriptorHelper{
static Future<BitmapDescriptor> getBitmapDescriptorFromSvgAsset(
BuildContext context, String svgAssetLink) async {
final svgImage = await _getSvgImageFromAssets(context, svgAssetLink);
final sizedSvgImage = await _getSizedSvgImage(svgImage);
final pngSizedBytes = await sizedSvgImage.toByteData(format: ui.ImageByteFormat.png);
final unit8List = pngSizedBytes.buffer.asUint8List();
return BitmapDescriptor.fromBytes(unit8List);
}
static Future<BitmapDescriptor> getBitmapDescriptorFromSvgString(String svgString) async {
final svgImage = await _getSvgImageFromString(svgString);
final sizedSvgImage = await _getSizedSvgImage(svgImage);
final pngSizedBytes = await sizedSvgImage.toByteData(format: ui.ImageByteFormat.png);
final unit8List = pngSizedBytes.buffer.asUint8List();
return BitmapDescriptor.fromBytes(unit8List);
}
static Future<ui.Image> _getSvgImageFromAssets(BuildContext context, String svgAssertLink) async {
String svgString = await DefaultAssetBundle.of(context).loadString(svgAssertLink);
DrawableRoot drawableRoot = svg.fromSvgString(svgString, null);
ui.Picture picture = drawableRoot.toPicture();
ui.Image image = await picture.toImage(
drawableRoot.viewport.width.toInt(), drawableRoot.viewport.height.toInt());
return image;
}
static Future<ui.Image> _getSvgImageFromString(String svgString) async {
DrawableRoot drawableRoot = svg.fromSvgString(svgString, null);
ui.Picture picture = drawableRoot.toPicture();
ui.Image image = await picture.toImage(
drawableRoot.viewport.width.toInt(), drawableRoot.viewport.height.toInt());
return image;
}
static Future<ui.Image> _getSizedSvgImage(ui.Image svgImage) async {
final size = 50 * ui.window.devicePixelRatio;
final width = size;
final height = width;
final ui.PictureRecorder pictureRecorder = ui.PictureRecorder();
final Canvas canvas = Canvas(pictureRecorder);
final Rect svgRect =
Rect.fromLTRB(0.0, 0.0, svgImage.width.toDouble(), svgImage.height.toDouble());
final Rect sizedRect = Rect.fromLTRB(0.0, 0.0, width, height); // owr size here
canvas.drawImageRect(svgImage, svgRect, sizedRect, Paint());
return await pictureRecorder.endRecording().toImage(width.toInt(), height.toInt());
}
}
from your widget class:
final icon = await BitmapDescriptorHelper.getBitmapDescriptorFromSvgAsset(
context, "assets/icons/some_svg_icon.svg");
final Marker marker = Marker(
icon: icon,
...
);
enjoy :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With