【发布时间】:2019-04-12 16:01:06
【问题描述】:
是否可以使用 SVG 路径通过 google_maps_flutter 插件创建标记?我知道您可以通过以下方式使用.png 文件:
icon: BitmapDescriptor.fromAsset("images/myFile.png")
SVG 路径怎么样?
谢谢
【问题讨论】:
是否可以使用 SVG 路径通过 google_maps_flutter 插件创建标记?我知道您可以通过以下方式使用.png 文件:
icon: BitmapDescriptor.fromAsset("images/myFile.png")
SVG 路径怎么样?
谢谢
【问题讨论】:
这可以使用flutter_svg 包来实现。
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());
}
然后您可以像往常一样使用 BitmapDescriptor 创建标记:
BitmapDescriptor bitmapDescriptor = await _bitmapDescriptorFromSvgAsset(context, 'assets/images/someimage.svg');
Marker marker = Marker(markerId: MarkerId('someId'), icon: bitmapDescriptor, position: LatLng(someLatitude, someLongitude));
【讨论】:
这里有几个选项:
getBitmapDescriptorFromSvgAsset - 来自资产的 svg getBitmapDescriptorFromSvgString - svg 作为来自 db/remote/whatever 的字符串class 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());
}
}
来自您的小部件类:
final icon = await BitmapDescriptorHelper.getBitmapDescriptorFromSvgAsset(
context, "assets/icons/some_svg_icon.svg");
final Marker marker = Marker(
icon: icon,
...
);
享受:)
【讨论】:
刚刚查看了 BitmapDescriptor 类的文档 可以试试 fromAssetImage() 类方法
【讨论】: