Skip to content

Instantly share code, notes, and snippets.

@CaiJingLong
Created January 9, 2025 00:59
Show Gist options
  • Save CaiJingLong/2e5ecc025ca2d7d0e109f7695d098830 to your computer and use it in GitHub Desktop.
Save CaiJingLong/2e5ecc025ca2d7d0e109f7695d098830 to your computer and use it in GitHub Desktop.
AMap BitmapDescriptor 生成,配合 image_editor image_size_getter + Asset 图片
import 'dart:math';
import 'dart:typed_data';
import 'package:amap_flutter_map/amap_flutter_map.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image_editor/image_editor.dart';
import 'package:image_size_getter/image_size_getter.dart' as isg;
import 'package:logmap/const/resource.dart';
class MapUtils {
static final _map = <String, BitmapDescriptor>{};
static BitmapDescriptor getAMapBitmap(String assetKey) {
if (!_map.containsKey(assetKey)) {
throw Exception('$assetKey not found');
}
return _map[assetKey]!;
}
static Future<BitmapDescriptor> prepareBitmapDescriptor(
String assetKey,
) async {
if (_map.containsKey(assetKey)) {
return _map[assetKey]!;
}
Uint8List iconData;
final data = await rootBundle.load(assetKey);
final src = data.buffer.asUint8List();
final option = ImageEditorOption();
option.addOption(const ScaleOption(64, 64));
option.outputFormat = const OutputFormat.png();
final result =
await ImageEditor.editImage(image: src, imageEditorOption: option);
if (result == null) {
iconData = src;
} else {
iconData = result;
}
BitmapDescriptor prepared = BitmapDescriptor.fromBytes(iconData);
_map[assetKey] = prepared;
return prepared;
}
static final _carMarkerMap = <String, BitmapDescriptor>{};
static void clearCache() {
_carMarkerMap.clear();
_map.clear();
}
static Future<BitmapDescriptor?> makeMarkerBitmap(String carNumber) async {
if (_carMarkerMap.containsKey(carNumber)) {
return _carMarkerMap[carNumber]!;
}
final srcBottom = await _getAssetBytes(R.ASSETS_CAR_ICON_2_PNG); // 车 icon 不透明
// final srcBottom = await _getAssetBytes(R.ASSETS_CAR_ICON_3_PNG); // 车 icon 透明
final srcTopBg = await _getAssetBytes(R.ASSETS_CAR_INFO_BG_PNG);
var bottomSize = isg.ImageSizeGetter.getSize(isg.MemoryInput(srcBottom));
final topSize = isg.ImageSizeGetter.getSize(isg.MemoryInput(srcTopBg));
final targetWidth = max(bottomSize.width, topSize.width);
final targetHeight = bottomSize.height + topSize.height;
final targetSize = Size(targetWidth.toDouble(), targetHeight.toDouble());
final bottomX = (targetWidth - bottomSize.width) / 2;
ImageMergeOption option = ImageMergeOption(
canvasSize: targetSize,
format: const OutputFormat.png(),
);
option.addImage(
MergeImageConfig(
position: ImagePosition(
Offset.zero,
Size(
topSize.width.toDouble(),
topSize.height.toDouble(),
),
),
image: ImageSource.memory(srcTopBg),
),
);
option.addImage(
MergeImageConfig(
position: ImagePosition(
Offset(bottomX, topSize.height.toDouble()),
Size(
bottomSize.width.toDouble(),
bottomSize.height.toDouble(),
),
),
image: ImageSource.memory(srcBottom),
),
);
final merged = await ImageMerger.mergeToMemory(option: option);
if (merged == null) {
return null;
}
final addTextOption = ImageEditorOption();
addTextOption.addOption(
AddTextOption()
..addText(
EditorText(
text: carNumber,
offset: const Offset(15, 10),
textColor: Colors.white,
),
),
);
addTextOption.outputFormat = const OutputFormat.png();
final result = await ImageEditor.editImage(
image: merged,
imageEditorOption: addTextOption,
);
if (result == null) {
return null;
}
final bitmapDescription = BitmapDescriptor.fromBytes(result);
_carMarkerMap[carNumber] = bitmapDescription;
return bitmapDescription;
}
static Future<Uint8List> _getAssetBytes(String key) async {
final byteData = await rootBundle.load(key);
return byteData.buffer.asUint8List();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment