我是Flutter的新手,我正在尝试为谷歌地图创建一个自定义标记。到目前为止,我已经能够从画布上创建一个带有笔划、背景颜色和图标的圆圈,但我需要从资源中添加背景图像,而不是图标。这是我的代码:
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());
}
void paintCircleFill(Canvas canvas, Color color) {
final paint = Paint()
..style = PaintingStyle.fill
..color = color;
canvas.drawCircle(Offset(circleOffset, circleOffset), innerRadius, paint);
}
void paintCircleStroke(Canvas canvas, Color color) {
final paint = Paint()
..style = PaintingStyle.stroke
..color = color
..strokeWidth = (stroke);
canvas.drawCircle(Offset(circleOffset, circleOffset), outerRadius, paint);
}
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,
color: color,
));
textPainter.layout();
textPainter.paint(canvas, Offset(iconOffset, iconOffset));
}
每次要创建位图图标时,使用此类并仅调用函数createBitmapDescriptorFromIconData
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);