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();
}
함수에 마커에 사용할 아이콘 경로와 지도에 나타날 마커의 width를 입력하면 Future 타입의 result 값을 반환한다.
Uint8List란?
8비트의 부호 없는 정수인 고정된 길이의 리스트
긴 리스트의 경우 기본 구현보다 더 효율적이다.
asset의 사진 파일에 접근
rootBundle.load(path)
asset에 포함된 파일들은 AssetBundle object를 통해 접근한다.
rootBundle object를 사용하면 BuildContext없이 asset에 접근할 수 있다.
이미지 Codec을 인스턴스화
ui.instantiateImageCodec
이미지 Codec을 인스턴스화한다.
list는 binary image data로 지원되는 이미지 형식은 PNG, JPEG, GIF 등이 있다.
targetWidth와 targetHeight를 통해 이미지의 크기를 이미지 픽셀 단위로 지정한다.
위의 코드를 구글맵의 marker icon에 넣어 사용할 수 있다. 이 때 Future이기 때문에 provider에서 async await 처리를 해주어야 한다.
// provider
late Uint8List customIcon;
void setCustomMapPin() async{
customIcon = await CustomMarker().getBytesFromAsset("path", 130);
}
await을 통해 Uint8List로 한 겹 벗겨주고 customIcon을 구글맵 마커에 넣어준다.
markers: {
Marker(
markerId: const MarkerId("currentLocation"),
icon: BitmapDescriptor.fromBytes(RidingProvider().customIcon),
position: LatLng(_ridingProvider.position?.latitude ?? 37.343991285297, _ridingProvider.position?.longitude ?? 126.74729588817)
)
},
Uri uri = Uri.parse(path);
final http.Response response = await http.get(uri);
BitmapDescriptor.fromBytes(response.bodyBytes);
하지만 매번 모든 마커에 대해 네트워크 요청을 수행하고 있어 로딩이 지연될 수 있다. 또한 이미지 크기를 조정해 마커를 만들어야 한다.
안녕하세요! 혹시 전체 코드를 볼수있는 깃허브 링크가 있을까요..? 계속 봤는데 이해 안되는 부분이 있어서요 ㅜㅜ