Flutter 图像叠加于 Google 地图标记。

5

我希望在谷歌地图标记上显示用户的图片,但我不知道如何实现?

这里是我想要的结果:

标记图片:

enter image description here

我想要的结果:

enter image description here

非常感谢

4个回答

2
如果您要使用本地资源,可以像@CopsOnRoad所说的那样轻松完成,但是,如果您要从网络加载,我建议目前使用Flutter map inspire in Leaflet,我已经使用了一段时间,它工作得非常好。"最初的回答"

我已经检查过了,但我的主要问题是关于在另一张图片上叠加图像的问题。 - amorenew
你可以在地图中使用小部件,因此您可以使用 Stack 创建叠加层并添加所需的叠加层 :D - Argel Bejarano
我没有使用谷歌地图,因为它不被支持。我会给你发送另一个地图插件 flutter_map 的链接,这个插件允许使用小部件,并且你可以在标记中使用任何想要的小部件。点击我帖子中放置的链接 :D - Argel Bejarano

1

解决方案仓库: https://github.com/amorenew/Flutter_avatar_maps

我使用了这个库:

  image: ^2.1.4

我的 main.dart

import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image/image.dart' as Images;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();

  Future<List<int>> makeReceiptImage() async {
    // load avatar image
    ByteData imageData = await rootBundle.load('assets/av.png');
    List<int> bytes = Uint8List.view(imageData.buffer);
    var avatarImage = Images.decodeImage(bytes);

    //load marker image 
    imageData = await rootBundle.load('assets/ma.png');
    bytes = Uint8List.view(imageData.buffer);
    var markerImage = Images.decodeImage(bytes);

    //resize the avatar image to fit inside the marker image
    avatarImage = Images.copyResize(avatarImage,
        width: markerImage.width ~/ 1.1, height: markerImage.height ~/ 1.4);


    var radius = 90;
    int originX = avatarImage.width ~/ 2, originY = avatarImage.height ~/ 2;

    //draw the avatar image cropped as a circle inside the marker image
    for (int y = -radius; y <= radius; y++)
      for (int x = -radius; x <= radius; x++)
        if (x * x + y * y <= radius * radius)
          markerImage.setPixelSafe(originX + x+8, originY + y+10,
              avatarImage.getPixelSafe(originX + x, originY + y));


    return Images.encodePng(markerImage);
  }
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  List<int> myImage;
  void _incrementCounter() {
    widget.makeReceiptImage().then((List<int> image) {
      setState(() {
        myImage = image;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.brown.shade100,
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            myImage == null ? Text('fdassd') : Image.memory(myImage),
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

0

目前来看,你不能真正地将Widget用于Marker,但是这里有一个你可以尝试的方法(我个人没有测试过)

var image = await BitmapDescriptor.fromAssetImage(
  ImageConfiguration(),
  "assets/images/your_image.jpg",
);

Marker marker = Marker(
  markerId: MarkerId("id"),
  icon: image,
);

我的问题是如何将一张图片添加到另一张图片上方,然后将其用作标记。 - amorenew
1
那就是我所说的,目前你不能像那样使用它。 - CopsOnRoad
如果我找不到覆盖图像的解决方案,那么我应该开一个问题。 - amorenew
根据这个问题,我会开一个issue,相信Flutter团队会有解决方案。 - amorenew

-1

我可以提供一些解决方案,有一个不错的库https://www.npmjs.com/package/merge-images, 通常当您遍历标记数组时,将2个或更多图像合并到base 64。以下是代码片段:

getMarkerImage(elementMarker, fullArray) {
    mergeImages([
      { src: './assets/img/markers/map-marker64.png', x: 0, y: 0 },
      { src: elementMarker.info.image || './assets/img/markers/markerIcon42.png', x: 11, y: 4 },
    ])
      .then(imgData => {
        console.log(imgData);
        this.markersImages.push(imgData);
        if (this.markersImages.length === this.controllersfullArray - 4) {
          fullArray.forEach((element, i) => {
            this.markers.push({
              lat: element.info.location.latitude,
              lng: element.info.location.longitude,
              controllerInfo: element.info,
              icon: {
                url: this.markersImages[i],
                labelOrigin: { x: 32, y: -10 },
                scaledSize: {
                  width: 64,
                  height: 64
                }
              },
              controllerStaus: element.status,
              label: {
                text: element.info.siteName,
                color: "#ED2C2C",
                fontWeight: "500",
                fontSize: "14px"
              }
            });
            console.log(this.markers);
          });
        }
      });
    // return (mergeImages({ src: './assets/img/markers/map-marker64.png', x: 0, y: 0 },
  }

但请注意,您需要使用在同一域上的所有图像。因为如果不这样做,toDataUrl 将抛出跨域错误


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接