Google maps 如何在flatter中更改谷歌地图标记的图标大小?
我在我的Flitter应用程序中使用了Google maps 如何在flatter中更改谷歌地图标记的图标大小?,google-maps,flutter,dart,Google Maps,Flutter,Dart,我在我的Flitter应用程序中使用了google\u maps\u flatter来使用google map我有自定义标记图标,我用BitmapDescriptor.fromAsset(“images/car.png”)加载它,但是我在地图上的图标太大了,我想把它缩小,但我找不到任何选项,因为有任何选项可以更改自定义标记图标。 这是我的颤振代码: mapController.addMarker( MarkerOptions( icon: BitmapDesc
google\u maps\u flatter
来使用google map我有自定义标记图标,我用BitmapDescriptor.fromAsset(“images/car.png”)
加载它,但是我在地图上的图标太大了,我想把它缩小,但我找不到任何选项,因为有任何选项可以更改自定义标记图标。
这是我的颤振代码:
mapController.addMarker(
MarkerOptions(
icon: BitmapDescriptor.fromAsset("images/car.png"),
position: LatLng(
deviceLocations[i]['latitude'],
deviceLocations[i]['longitude'],
),
),
);
下面是我的android模拟器的屏幕截图:
正如您在图片中所看到的,我的自定义图标尺寸太大了,因此您可以尝试这种丑陋的方式。MediaQuery将返回比率并手动检查条件,如
double mq = MediaQuery.of(context).devicePixelRatio;
String icon = "images/car.png";
if (mq>1.5 && mq<2.5) {icon = "images/car2.png";}
else if(mq >= 2.5){icon = "images/car3.png";}
mapController.addMarker(
MarkerOptions(
icon: BitmapDescriptor.fromAsset(icon),
position: LatLng(37.4219999, -122.0862462),
),
);
我发现解决这个问题的一个简单方法是
BitmapDescriptor get deliveryIcon {
bool isIOS = Theme.of(context).platform == TargetPlatform.iOS;
if (isIOS)
return BitmapDescriptor.fromAsset('assets/icons/orange_pin.png');
else
return BitmapDescriptor.fromAsset(
'assets/icons/3.0x/orange_pin.png');
}
简单地说,为android提供更大的资源。应避免使用大型图像,因为它们会消耗不必要的空间。应根据地图缩放图像,并根据设备的不同像素分辨率进行调整 例如,应将基础图像缩放到应用程序外部的正确大小。不同的设备有不同的像素分辨率,这正是flatter所能满足的。需要不同版本的图像,以便图像不会出现锯齿状。按不同分辨率放大图像。i、 e基本版本32x32像素,版本2.0将为64x64像素,版本3.0将为128x128等。请参阅下文所述的标准颤振方式,该方式可满足不同像素分辨率的要求,具体取决于设备制造商
BitmapDescriptor.fromAsset不支持像素分辨率的自动解码,将加载路径中指定的文件。要更正此调用,请使用AssetImage解码正确的文件名 图像呈现有一个bug,iOS中的图像看起来比Android大,请参见缺陷。这也有一个解决方法,通过硬编码您想要的解析的文件名 以下各节概述了标准颤振方式、AssetImage解决方案和24865解决方案 标准颤振图像命名约定 创建具有以下名称的资源文件夹: 其中M和N是分辨率(2.0x)或主题(暗)。 然后将图像或所有图像添加到pubspec.file中,如下所示:
flutter:
assets:
- pathtoimages/image.png
或
谷歌地图的解决方案
该标准要求使用AssetImages('pathtoimages/image.png')加载图像,这是google地图插件不支持的。Google maps要求您使用BitmapDescriptor.fromAsset('pathtoimages/image.png'),但此时无法解析为正确的图像。要解决此问题,您可以首先使用定义的BuildContext创建LocalimageConfiguration,从AssetImage获得正确的图像。然后使用此配置解析正确的图像,如下所示:
ImageConfiguration config = createLocalImageConfiguration(context);
AssetImage('pathtoimages/image.png')
.obtainKey(config)
.then((resolvedImage) {
print('Name: ' + resolvedImage.onValue.name);
});
缺陷解决方法
BitmapDescriptor get deliveryIcon {
bool isIOS = Theme.of(context).platform == TargetPlatform.iOS;
If (isIOS)
return BitmapDescriptor.fromAsset('pathtoimages/image.png');
else
return BitmapDescriptor.fromAsset(
resolvedImageName);
}
BitmapDescriptor.fromAsset()是添加标记的正确方法,只有一个打开的bug会影响代码。正如Saed所回答的,您需要为不同的设备屏幕密度提供不同大小的图像。根据您提供的图像,我猜您想要的图像的基本大小大约为48像素。因此,您需要制作大小为48、96(2.0x)和144(3.0x)的副本
运行时应根据屏幕密度选择正确的选项。看
目前,这并不是在Android或Fuschia上自动完成的。如果您现在正在发布并希望解决此问题,则可以使用以下逻辑检查平台:
MediaQueryData data = MediaQuery.of(context);
double ratio = data.devicePixelRatio;
bool isIOS = Theme.of(context).platform == TargetPlatform.iOS;
如果平台不是iOS,您将在代码中实现bucket。将逻辑组合成一种方法:
String imageDir(String prefix, String fileName, double pixelRatio, bool isIOS) {
String directory = '/';
if (!isIOS) {
if (pixelRatio >= 1.5) {
directory = '/2.0x/';
}
else if (pixelRatio >= 2.5) {
directory = '/3.0x/';
}
else if (pixelRatio >= 3.5) {
directory = '/4.0x/';
}
}
return '$prefix$directory$fileName';
}
然后,您可以使用以下代码为资产目录**assets/map_icons/**中名为person_icon的图标创建标记,方法如下:
myLocationMarker = Marker(
markerId: MarkerId('myLocation'),
position: showingLocation, flat: true,
icon: BitmapDescriptor.fromAsset(imageDir('assets/map_icons','person_icon.png', ratio, isIos)));
请尝试BitmapDescriptor.fromAssetImage。它也将忽略图像大小
BitmapDescriptor.fromAssetImage(
ImageConfiguration(size: Size(32, 32)), 'assets/car.png')
.then((onValue) {
setState(() {
markerIcon = onValue;
});
});
使用默认配置也会失败
loadMarkerImage(BuildContext context) {
var config = createLocalImageConfiguration(context, size: Size(30, 30));
BitmapDescriptor.fromAssetImage(config, 'assets/car.png')
.then((onValue) {
setState(() {
markerIcon = onValue;
});
});
}
是什么让我为不同的密度选择了正确的图像:
MediaQueryData mediaQueryData = MediaQuery.of(context);
ImageConfiguration imageConfig = ImageConfiguration(devicePixelRatio: mediaQueryData.devicePixelRatio);
BitmapDescriptor.fromAssetImage(imageConfig, "assets/images/marker.png");
TL;DR:只要您能够将任何图像编码为原始字节,如Uint8List
,就可以将其用作标记
现在,您可以使用
Uint8List
数据使用谷歌地图创建标记。这意味着您可以使用原始数据绘制任何您想要的地图标记,只要您保持正确的编码格式(在这个特定场景中,它是png
)
我将介绍两个示例,您可以选择:
1.使用资产 首先,创建一个处理资源路径并接收大小的方法(可以是宽度、高度或两者,但只使用一个将保留比率) 这将分别产生50、100和200宽度的以下结果
2.使用画布 你可以用画布画任何你想画的东西,然后用它作为标记。下面将生成一个带有
Hello world的简单圆形框代码>其中的文本
首先,用画布画一些东西:
Future<Uint8List> getBytesFromCanvas(int width, int height) async {
final ui.PictureRecorder pictureRecorder = ui.PictureRecorder();
final Canvas canvas = Canvas(pictureRecorder);
final Paint paint = Paint()..color = Colors.blue;
final Radius radius = Radius.circular(20.0);
canvas.drawRRect(
RRect.fromRectAndCorners(
Rect.fromLTWH(0.0, 0.0, width.toDouble(), height.toDouble()),
topLeft: radius,
topRight: radius,
bottomLeft: radius,
bottomRight: radius,
),
paint);
TextPainter painter = TextPainter(textDirection: TextDirection.ltr);
painter.text = TextSpan(
text: 'Hello world',
style: TextStyle(fontSize: 25.0, color: Colors.white),
);
painter.layout();
painter.paint(canvas, Offset((width * 0.5) - painter.width * 0.5, (height * 0.5) - painter.height * 0.5));
final img = await pictureRecorder.endRecording().toImage(width, height);
final data = await img.toByteData(format: ui.ImageByteFormat.png);
return data.buffer.asUint8List();
}
给你
我也有同样的问题,我用这种方法解决
Future < Uint8List > getBytesFromCanvas(int width, int height, urlAsset) async
{
final ui.PictureRecorder pictureRecorder = ui.PictureRecorder();
final Canvas canvas = Canvas(pictureRecorder);
final Paint paint = Paint()..color = Colors.transparent;
final Radius radius = Radius.circular(20.0);
canvas.drawRRect(
RRect.fromRectAndCorners(
Rect.fromLTWH(0.0, 0.0, width.toDouble(), height.toDouble()),
topLeft: radius,
topRight: radius,
bottomLeft: radius,
bottomRight: radius,
),
paint);
final ByteData datai = await rootBundle.load(urlAsset);
var imaged = await loadImage(new Uint8List.view(datai.buffer));
canvas.drawImage(imaged, new Offset(0, 0), new Paint());
final img = await pictureRecorder.endRecording().toImage(width, height);
final data = await img.toByteData(format: ui.ImageByteFormat.png);
return data.buffer.asUint8List();
}
Future < ui.Image > loadImage(List < int > img) async {
final Completer < ui.Image > completer = new Completer();
ui.decodeImageFromList(img, (ui.Image img) {
return completer.complete(img);
});
return completer.future;
}
我已经更新了上面的功能,现在你可以根据自己的喜好缩放图像
Future<Uint8List> getBytesFromCanvas(int width, int height, urlAsset) async {
final ui.PictureRecorder pictureRecorder = ui.PictureRecorder();
final Canvas canvas = Canvas(pictureRecorder);
final ByteData datai = await rootBundle.load(urlAsset);
var imaged = await loadImage(new Uint8List.view(datai.buffer));
canvas.drawImageRect(
imaged,
Rect.fromLTRB(
0.0, 0.0, imaged.width.toDouble(), imaged.height.toDouble()),
Rect.fromLTRB(0.0, 0.0, width.toDouble(), height.toDouble()),
new Paint(),
);
final img = await pictureRecorder.endRecording().toImage(width, height);
final data = await img.toByteData(format: ui.ImageByteFormat.png);
return data.buffer.asUint8List();
}
Future getBytesFromCanvas(int-width、int-height、urlAsset)异步{
final ui.PictureRecorder PictureRecorder=ui.PictureRecorder();
最终画布=画布(pictureRecorder);
final ByteData datai=等待rootBundle.load(urlAsset);
var imaged=await loadImage(新的Uint8List.view(datai.buffer));
canvas.drawImageRect(
想象,
Rect.fromLTRB(
0.0,0.0,图像
import 'dart:ui' as ui;
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();
}
final Uint8List markerIcon = await getBytesFromAsset('assets/images/flutter.png', 100);
final Marker marker = Marker(icon: BitmapDescriptor.fromBytes(markerIcon));
Future<Uint8List> getBytesFromCanvas(int width, int height) async {
final ui.PictureRecorder pictureRecorder = ui.PictureRecorder();
final Canvas canvas = Canvas(pictureRecorder);
final Paint paint = Paint()..color = Colors.blue;
final Radius radius = Radius.circular(20.0);
canvas.drawRRect(
RRect.fromRectAndCorners(
Rect.fromLTWH(0.0, 0.0, width.toDouble(), height.toDouble()),
topLeft: radius,
topRight: radius,
bottomLeft: radius,
bottomRight: radius,
),
paint);
TextPainter painter = TextPainter(textDirection: TextDirection.ltr);
painter.text = TextSpan(
text: 'Hello world',
style: TextStyle(fontSize: 25.0, color: Colors.white),
);
painter.layout();
painter.paint(canvas, Offset((width * 0.5) - painter.width * 0.5, (height * 0.5) - painter.height * 0.5));
final img = await pictureRecorder.endRecording().toImage(width, height);
final data = await img.toByteData(format: ui.ImageByteFormat.png);
return data.buffer.asUint8List();
}
final Uint8List markerIcon = await getBytesFromCanvas(200, 100);
final Marker marker = Marker(icon: BitmapDescriptor.fromBytes(markerIcon));
Future < Uint8List > getBytesFromCanvas(int width, int height, urlAsset) async
{
final ui.PictureRecorder pictureRecorder = ui.PictureRecorder();
final Canvas canvas = Canvas(pictureRecorder);
final Paint paint = Paint()..color = Colors.transparent;
final Radius radius = Radius.circular(20.0);
canvas.drawRRect(
RRect.fromRectAndCorners(
Rect.fromLTWH(0.0, 0.0, width.toDouble(), height.toDouble()),
topLeft: radius,
topRight: radius,
bottomLeft: radius,
bottomRight: radius,
),
paint);
final ByteData datai = await rootBundle.load(urlAsset);
var imaged = await loadImage(new Uint8List.view(datai.buffer));
canvas.drawImage(imaged, new Offset(0, 0), new Paint());
final img = await pictureRecorder.endRecording().toImage(width, height);
final data = await img.toByteData(format: ui.ImageByteFormat.png);
return data.buffer.asUint8List();
}
Future < ui.Image > loadImage(List < int > img) async {
final Completer < ui.Image > completer = new Completer();
ui.decodeImageFromList(img, (ui.Image img) {
return completer.complete(img);
});
return completer.future;
}
final Uint8List markerIcond = await getBytesFromCanvas(80, 98, urlAsset);
setState(() {
markersMap[markerId] = Marker(
markerId: MarkerId("marker_${id}"),
position: LatLng(double.parse(place.lat), double.parse(place.lng)),
icon: BitmapDescriptor.fromBytes(markerIcond),
onTap: () {
_onMarkerTapped(placeRemote);
},
);
});
Future<Uint8List> getBytesFromCanvas(int width, int height, urlAsset) async {
final ui.PictureRecorder pictureRecorder = ui.PictureRecorder();
final Canvas canvas = Canvas(pictureRecorder);
final ByteData datai = await rootBundle.load(urlAsset);
var imaged = await loadImage(new Uint8List.view(datai.buffer));
canvas.drawImageRect(
imaged,
Rect.fromLTRB(
0.0, 0.0, imaged.width.toDouble(), imaged.height.toDouble()),
Rect.fromLTRB(0.0, 0.0, width.toDouble(), height.toDouble()),
new Paint(),
);
final img = await pictureRecorder.endRecording().toImage(width, height);
final data = await img.toByteData(format: ui.ImageByteFormat.png);
return data.buffer.asUint8List();
}
Future<Uint8List> getBytesFromCanvas(double escala, urlAsset) async {
final ui.PictureRecorder pictureRecorder = ui.PictureRecorder();
final Canvas canvas = Canvas(pictureRecorder);
final ByteData datai = await rootBundle.load(urlAsset);
var imaged = await loadImage(new Uint8List.view(datai.buffer));
double width = ((imaged.width.toDouble() * escala).toInt()).toDouble();
double height = ((imaged.height.toDouble() * escala).toInt()).toDouble();
canvas.drawImageRect(imaged, Rect.fromLTRB(0.0, 0.0, imaged.width.toDouble(), imaged.height.toDouble()),
Rect.fromLTRB(0.0, 0.0, width, height),
new Paint(),
);
final img = await pictureRecorder.endRecording().toImage(width.toInt(), height.toInt());
final data = await img.toByteData(format: ui.ImageByteFormat.png);
return data.buffer.asUint8List();
}
Future < ui.Image > loadImage(List < int > img) async {
final Completer < ui.Image > completer = new Completer();
ui.decodeImageFromList(img, (ui.Image img) {
return completer.complete(img);
});
return completer.future;
}
var iconTour;
bool isIOS = Theme.of(context).platform == TargetPlatform.iOS;
if (isIOS){
final markerIcon = await getBytesFromCanvas(0.7, 'images/Icon.png');
iconTour = BitmapDescriptor.fromBytes(markerIcon);
}
else{
final markerIcon = await getBytesFromCanvas(1, 'images/Icon.png');
iconTour = BitmapDescriptor.fromBytes(markerIcon);
}
setState(() {
final Marker marker = Marker(icon: iconTour);
});
google_maps_flutter: ^0.5.19
Future setMarkersPoint() async {
var icon = 'your url';
Uint8List dataBytes;
var request = await http.get(icon);
var bytes = await request.bodyBytes;
setState(() {
dataBytes = bytes;
});
final Uint8List markerIcoenter code heren =
await getBytesFromCanvas(150, 150, dataBytes);
var myLatLong = LatLng(double.parse(-6.9024812),
double.parse(107.61881));
_markers.add(Marker(
markerId: MarkerId(myLatLong.toString()),
icon: BitmapDescriptor.fromBytes(markerIcon),
position: myLatLong,
infoWindow: InfoWindow(
title: 'Name of location',
snippet: 'Marker Description',
),
));
Future<Uint8List> getBytesFromCanvas(
int width, int height, Uint8List dataBytes) async {
final ui.PictureRecorder pictureRecorder = ui.PictureRecorder();
final Canvas canvas = Canvas(pictureRecorder);
final Paint paint = Paint()..color = Colors.transparent;
final Radius radius = Radius.circular(20.0);
canvas.drawRRect(
RRect.fromRectAndCorners(
Rect.fromLTWH(0.0, 0.0, width.toDouble(), height.toDouble()),
topLeft: radius,
topRight: radius,
bottomLeft: radius,
bottomRight: radius,
),
paint);
var imaged = await loadImage(dataBytes.buffer.asUint8List());
canvas.drawImageRect(
imaged,
Rect.fromLTRB(
0.0, 0.0, imaged.width.toDouble(), imaged.height.toDouble()),
Rect.fromLTRB(0.0, 0.0, width.toDouble(), height.toDouble()),
new Paint(),
);
final img = await pictureRecorder.endRecording().toImage(width, height);
final data = await img.toByteData(format: ui.ImageByteFormat.png);
return data.buffer.asUint8List();
}
Future<ui.Image> loadImage(List<int> img) async {
final Completer<ui.Image> completer = new Completer();
ui.decodeImageFromList(img, (ui.Image img) {
return completer.complete(img);
});
return completer.future;
}
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
Map<MarkerId, Marker> markers = <MarkerId, Marker>{};
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();
}
Future<void> _addMarker(tmp_lat, tmp_lng) async {
var markerIdVal = _locationIndex.toString();
final MarkerId markerId = MarkerId(markerIdVal);
final Uint8List markerIcon = await getBytesFromAsset('assets/img/pin2.png', 100);
// creating a new MARKER
final Marker marker = Marker(
icon: BitmapDescriptor.fromBytes(markerIcon),
markerId: markerId,
position: LatLng(tmp_lat, tmp_lng),
infoWindow: InfoWindow(title: markerIdVal, snippet: 'boop'),
);
setState(() {
// adding a new marker to map
markers[markerId] = marker;
});
}
flutter:
uses-material-design: true
assets:
- assets/img/pin1.png
- assets/img/pin2.png
images/car.png <-- if this base image is 100x100px
images/2.0x/car.png <-- 2.0x one should be 200x200px
images/3.0x/car.png <-- and 3.0x one should be 300x300px
mapController.addMarker(
MarkerOptions(
icon: BitmapDescriptor.fromAssetImage(
createLocalImageConfiguration(context),
"images/car.png"),
position: LatLng(
deviceLocations[i]['latitude'],
deviceLocations[i]['longitude'],
),
),
);
import 'dart:ui' as ui;
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
Future<Uint8List> getBytesFromAsset(String path) async {
double pixelRatio = MediaQuery.of(context).devicePixelRatio;
ByteData data = await rootBundle.load(path);
ui.Codec codec = await ui.instantiateImageCodec(
data.buffer.asUint8List(),
targetWidth: pixelRatio.round() * 30
);
ui.FrameInfo fi = await codec.getNextFrame();
return (await fi.image.toByteData(format: ui.ImageByteFormat.png)).buffer.asUint8List();
}
final Uint8List markerIcon = await getBytesFromAsset('assets/images/bike.png');
Marker(icon: BitmapDescriptor.fromBytes(markerIcon),)