我正在使用谷歌地图来显示用户位置。我需要一个自定义标记来显示用户位置。用户图像是从网址获取的。但我无法获得像图像中所示的形状的标记。我的代码如下。使用我的代码,我无法实现所需的背景形状。有人请帮我解决这个问题。
Future<void> 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 = Utils.myColor.primary;
final double tagWidth = 20.0;
final Paint shadowPaint = Paint()..color = Colors.white;
final double shadowWidth = 2.0;
final Paint borderPaint = Paint()..color = Colors.white;
final double borderWidth = 2.0;
final double imageOffset = shadowWidth + borderWidth;
// Add shadow circle
canvas.drawRRect(
RRect.fromRectAndCorners(
Rect.fromLTWH(0.0, 0.0, size.width, 100),
topLeft: radius,
topRight: radius,
bottomLeft: radius,
bottomRight: radius,
),
shadowPaint);
// Add border circle
canvas.drawRRect(
RRect.fromRectAndCorners(
Rect.fromLTWH(
shadowWidth, shadowWidth, size.width - (shadowWidth * 2), 100),
topLeft: radius,
topRight: radius,
bottomLeft: radius,
bottomRight: radius,
),
borderPaint);
// 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(), 100);
// Convert image to bytes
final ByteData byteData =
await markerAsImage.toByteData(format: ui.ImageByteFormat.png);
final Uint8List uint8List = byteData.buffer.asUint8List();
setState(() {
markerIcon = BitmapDescriptor.fromBytes(uint8List);
});
}
Future<ui.Image> getImageFromPath(String imagePath) async {
File imageFile = await DefaultCacheManager().getSingleFile(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;
}
查看 https://pub.dev/packages/custom_map_markers 将任何小部件渲染为标记。使用小部件可能会更容易实现您想要的特定外观
class _PostedMapState extends State<PostedMap> {
Completer<GoogleMapController> _mapController = Completer();
Uint8List imageDataBytes;
var markerIcon;
GlobalKey iconKey = GlobalKey();
@override
void initState() {
super.initState();
// if (widget.userImage != '') {
// Future.delayed(Duration(seconds: 5), () {
// getCustomMarkerIcon(iconKey);
// });
// }
WidgetsBinding.instance.addPostFrameCallback(getCustomMarkerIcon(iconKey));
}
@override
Widget build(BuildContext context) {
// TODO: implement build.
return Container(
height: widget.height,
width: widget.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
),
// margin: EdgeInsets.only(left: 20, right: 20),
child: Stack(
children: [
getMarkerWidget(),
Card(
child: GoogleMap(
mapType: MapType.normal,
onTap: (x) {
MapsLauncher.launchCoordinates(
widget.checkInLat.toDouble(), widget.checkInLon.toDouble());
},
zoomControlsEnabled: false,
zoomGesturesEnabled: false,
mapToolbarEnabled: false,
trafficEnabled: false,
tiltGesturesEnabled: false,
scrollGesturesEnabled: false,
rotateGesturesEnabled: false,
myLocationEnabled: false,
liteModeEnabled: false,
indoorViewEnabled: false,
initialCameraPosition: CameraPosition(
target: LatLng(
double.parse(widget.checkInLat),
double.parse(widget.checkInLon),
),
zoom: 14.4746,
),
onMapCreated: (GoogleMapController controller) {
controller.setMapStyle(mapStyle);
// _mapController = controller;
try {
_mapController.complete(controller);
} catch (err) {
Log.e("err", err);
}
},
myLocationButtonEnabled: false,
markers: Set<Marker>.of(
<Marker>[
Marker(
draggable: false,
markerId: MarkerId(widget.userImage),
position: LatLng(double.parse(widget.checkInLat),
double.parse(widget.checkInLon)),
// icon: currentLocationIcon,
icon: markerIcon ?? BitmapDescriptor.defaultMarker),
],
),
),
),
],
),
);
}
Future<void> getCustomMarkerIcon(GlobalKey iconKey) async {
RenderRepaintBoundary boundary = iconKey.currentContext.findRenderObject();
ui.Image image = await boundary.toImage(pixelRatio: 3.0);
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
var pngBytes = byteData.buffer.asUint8List();
setState(() {
markerIcon = BitmapDescriptor.fromBytes(pngBytes);
});
}
getMarkerWidget() {
return Transform.translate(
offset: Offset(50, 50),
child: RepaintBoundary(
key: iconKey,
child: SizedBox(
height: 40,
width: 40,
child: Stack(
children: [
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'${ASSETS.assetImage("/map_pin_icon2.png")}'),
fit: BoxFit.fitHeight,
),
),
),
Positioned(
left: 5,
top: 6,
child: ClipOval(
child: Container(
width: 20,
height: 20,
child: CommonWidgets().buildCachedNetworkImage(
'${widget.userImage}',
),
),
),
)
],
),
),
),
);
}
}
尝试使用这个在线工具。这些对我帮助很大。 shapemaker.web.app
//为旅行计划地图创建自定义标记 未来 createMarkerWithCustomIcon(String imageUrl, LatLng 位置, 字符串标记标题、函数()? onTap) 异步 { 最终 BitmapDescriptor 自定义图标 = 等待 getMarkerIcon(imageUrl, Size(150, 150));
最终标记标记 = 标记( 标记 ID: 标记 ID(标记标题), 位置: 位置, 图标:自定义图标, 点按:点按, );
返回标记; }
Future getMarkerIcon(String imageUrl, Size size) async { 最终 ui.PictureRecorder pictureRecorder = ui.PictureRecorder(); 最终 Canvas 画布 = Canvas(pictureRecorder); 最终 Radius 半径 = Radius.circular(size.width / 2);
最终绘制shadowPaint = Paint()..color = Colors.white.withAlpha(100); 最终双阴影宽度 = 15.0;
最终Paint borderPaint = Paint()..color = Colors.white; 最终双边框宽度 = 3.0;
最终双图像偏移=shadowWidth + borderWidth;
//阴影圈 画布.drawRRect( RRect.fromRectAndCorners( 矩形.fromLTWH(0.0, 0.0, 尺寸.宽度, 尺寸.高度), 左上角:半径, 右上角:半径, 左下角:半径, 右下角:半径, ), 阴影绘画);
//边框圆 画布.drawRRect( RRect.fromRectAndCorners( Rect.fromLTWH(shadowWidth, ShadowWidth, size.width - (shadowWidth * 2), 尺寸.高度 - (shadowWidth * 2)), 左上角:半径, 右上角:半径, 左下角:半径, 右下角:半径, ), 边框绘制);
// 图像的椭圆形 矩形椭圆 = Rect.fromLTWH(imageOffset, imageOffset, size.width - (imageOffset * 2), size.height - (imageOffset * 2));
// 剪切图像的椭圆形路径 canvas.clipPath(Path()..addOval(椭圆形));
// 获取并绘制网络图像 ui.Image 图像=等待_fetchNetworkImage(imageUrl); PaintImage(画布:画布,图像:图像,矩形:椭圆形,适合:BoxFit.cover);
// 将画布转换为图像 最终 ui.ImagemarkerAsImage = 等待 pictureRecorder .endRecording() .toImage(size.width.toInt(), size.height.toInt());
// 将图像转换为字节 最终的字节数据?字节数据 = 等待markerAsImage.toByteData(格式:ui.ImageByteFormat.png); 最终 Uint8List uint8List = byteData!.buffer.asUint8List();
返回 BitmapDescriptor.fromBytes(uint8List); }
未来