Flutter 颤振从画布创建谷歌地图自定义标记

Flutter 颤振从画布创建谷歌地图自定义标记,flutter,google-maps,dart,Flutter,Google Maps,Dart,我是一个新手,我正在尝试为谷歌地图创建一个自定义标记。 到目前为止,我已经能够从画布上创建一个带有笔划、背景颜色和图标的圆,但我需要从资源中添加一个背景图像,而不是图标。 这是我的代码: Future<BitmapDescriptor> createCustomMarkerBitmap({IconData iconData, Color iconColor, Color fillColor, Color strokeColor}) async { ByteData dat

我是一个新手,我正在尝试为谷歌地图创建一个自定义标记。 到目前为止,我已经能够从画布上创建一个带有笔划、背景颜色和图标的圆,但我需要从资源中添加一个背景图像,而不是图标。 这是我的代码:

  Future<BitmapDescriptor> createCustomMarkerBitmap({IconData iconData, Color iconColor, Color fillColor, Color strokeColor}) async {
    ByteData data = await rootBundle.load('assets/images/iconTry.png');
    Uint8List lst = new Uint8List.view(data.buffer);
    Codec codec = await ui.instantiateImageCodec(lst);
    FrameInfo frame = await codec.getNextFrame();
    final pictureRecorder = PictureRecorder();
    final canvas = Canvas(pictureRecorder); 
    paintCircleFill(canvas, fillColor);
    paintCircleStroke(canvas, strokeColor);
    paintIcon(canvas, iconColor, iconData);
    paintBackgroundImage(canvas, frame.image);
    final picture = pictureRecorder.endRecording();
    final image = await picture.toImage(markerSize, markerSize);
    final bytes = await image.toByteData(format: ImageByteFormat.png);
    BitmapDescriptor.fromBytes(bytes.buffer.asUint8List());

使用此类并在每次要创建bitmapIcon时仅调用函数
createBitMapDescriptorFromiconda

class MarkerGenerator {
  final _markerSize;
  double _circleStrokeWidth;
  double _circleOffset;
  double _outlineCircleWidth;
  double _fillCircleWidth;
  double _iconSize;
  double _iconOffset;

  MarkerGenerator(this._markerSize) {
    // calculate marker dimensions
    _circleStrokeWidth = _markerSize / 12.0;
    _circleOffset = _markerSize / 2;
    _outlineCircleWidth = _circleOffset - (_circleStrokeWidth / 2);
    _fillCircleWidth = _markerSize / 2;
    final outlineCircleInnerWidth = _markerSize - (2 * _circleStrokeWidth);
    _iconSize = sqrt(pow(outlineCircleInnerWidth, 2) / 4);
    final rectDiagonal = sqrt(2 * pow(_markerSize, 2));
    final circleDistanceToCorners = (rectDiagonal - outlineCircleInnerWidth) / 2;
    _iconOffset = sqrt(pow(circleDistanceToCorners, 2) / 1);
  }

  /// Creates a BitmapDescriptor from an IconData
  Future<BitmapDescriptor> createBitmapDescriptorFromIconData(IconData iconData, Color iconColor, Color circleColor, Color backgroundColor) async {
    final pictureRecorder = PictureRecorder();
    final canvas = Canvas(pictureRecorder);

    _paintCircleFill(canvas, backgroundColor);
    _paintCircleStroke(canvas, circleColor);
    _paintIcon(canvas, iconColor, iconData);

    final picture = pictureRecorder.endRecording();
    final image = await picture.toImage(_markerSize.round(), _markerSize.round());
    final bytes = await image.toByteData(format: ImageByteFormat.png);

    return BitmapDescriptor.fromBytes(bytes.buffer.asUint8List());
  }

  /// Paints the icon background
  void _paintCircleFill(Canvas canvas, Color color) {
    final paint = Paint()
      ..style = PaintingStyle.fill
      ..color = color;
    canvas.drawCircle(Offset(_circleOffset, _circleOffset), _fillCircleWidth, paint);
  }

  /// Paints a circle around the icon
  void _paintCircleStroke(Canvas canvas, Color color) {
    final paint = Paint()
      ..style = PaintingStyle.stroke
      ..color = color
      ..strokeWidth = _circleStrokeWidth;
    canvas.drawCircle(Offset(_circleOffset, _circleOffset), _outlineCircleWidth, paint);
  }

  /// Paints the icon
  void _paintIcon(Canvas canvas, Color color, IconData iconData) {
    final textPainter = TextPainter(textDirection: TextDirection.ltr);
    textPainter.text = TextSpan(
        text: String.fromCharCode(iconData.codePoint),
        style: TextStyle(
          letterSpacing: 0.0,
          fontSize: _iconSize,
          fontFamily: iconData.fontFamily,
          package: iconData.fontPackage,
          color: color,
        ));
    textPainter.layout();
    textPainter.paint(canvas, Offset(_iconOffset, _iconOffset));
  }
}

你能发布你的整个函数吗?@dm_tr这是我使用canvas final picture=pictureRecorder.endRecording()的最后一部分;最终图像=wait picture.toImage(markerSize,markerSize);最终字节=wait image.toByteData(格式:ImageByteFormat.png);BitmapDescriptor.fromBytes(bytes.buffer.asUint8List());检查下面的答案,但这样我只能使用已经存在的图标,对吗?我无法从AssetInteresting导入图像。有没有一种方法可以将资产与画布结合起来,这样我就可以用彩色边框画出我的圆圈,并坚持我的图像?好的,正如我所期待的那样。非常感谢你!不客气。很高兴helped@dm_tr如何删除图标周围的边框圈,并保持信息窗口接触核心图标的位置正确?
class MarkerGenerator {
  final _markerSize;
  double _circleStrokeWidth;
  double _circleOffset;
  double _outlineCircleWidth;
  double _fillCircleWidth;
  double _iconSize;
  double _iconOffset;

  MarkerGenerator(this._markerSize) {
    // calculate marker dimensions
    _circleStrokeWidth = _markerSize / 12.0;
    _circleOffset = _markerSize / 2;
    _outlineCircleWidth = _circleOffset - (_circleStrokeWidth / 2);
    _fillCircleWidth = _markerSize / 2;
    final outlineCircleInnerWidth = _markerSize - (2 * _circleStrokeWidth);
    _iconSize = sqrt(pow(outlineCircleInnerWidth, 2) / 4);
    final rectDiagonal = sqrt(2 * pow(_markerSize, 2));
    final circleDistanceToCorners = (rectDiagonal - outlineCircleInnerWidth) / 2;
    _iconOffset = sqrt(pow(circleDistanceToCorners, 2) / 1);
  }

  /// Creates a BitmapDescriptor from an IconData
  Future<BitmapDescriptor> createBitmapDescriptorFromIconData(IconData iconData, Color iconColor, Color circleColor, Color backgroundColor) async {
    final pictureRecorder = PictureRecorder();
    final canvas = Canvas(pictureRecorder);

    _paintCircleFill(canvas, backgroundColor);
    _paintCircleStroke(canvas, circleColor);
    _paintIcon(canvas, iconColor, iconData);

    final picture = pictureRecorder.endRecording();
    final image = await picture.toImage(_markerSize.round(), _markerSize.round());
    final bytes = await image.toByteData(format: ImageByteFormat.png);

    return BitmapDescriptor.fromBytes(bytes.buffer.asUint8List());
  }

  /// Paints the icon background
  void _paintCircleFill(Canvas canvas, Color color) {
    final paint = Paint()
      ..style = PaintingStyle.fill
      ..color = color;
    canvas.drawCircle(Offset(_circleOffset, _circleOffset), _fillCircleWidth, paint);
  }

  /// Paints a circle around the icon
  void _paintCircleStroke(Canvas canvas, Color color) {
    final paint = Paint()
      ..style = PaintingStyle.stroke
      ..color = color
      ..strokeWidth = _circleStrokeWidth;
    canvas.drawCircle(Offset(_circleOffset, _circleOffset), _outlineCircleWidth, paint);
  }

  /// Paints the icon
  void _paintIcon(Canvas canvas, Color color, IconData iconData) {
    final textPainter = TextPainter(textDirection: TextDirection.ltr);
    textPainter.text = TextSpan(
        text: String.fromCharCode(iconData.codePoint),
        style: TextStyle(
          letterSpacing: 0.0,
          fontSize: _iconSize,
          fontFamily: iconData.fontFamily,
          package: iconData.fontPackage,
          color: color,
        ));
    textPainter.layout();
    textPainter.paint(canvas, Offset(_iconOffset, _iconOffset));
  }
}
class Common {
  static Future<Uint8List> getBytesFromAsset(String path, int width) async {
    ByteData data = await rootBundle.load(path);
    ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(), targetWidth: width);
    ui.FrameInfo fi = await codec.getNextFrame();
    return (await fi.image.toByteData(format: ui.ImageByteFormat.png)).buffer.asUint8List();
  }
}
var bytes = await Common.getBytesFromAsset("your/asset/path", 100);
BitmapDescriptor.fromBytes(bytes);