Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Maps snapshot #1723

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import android.app.Application;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
Expand All @@ -37,6 +38,7 @@
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.platform.PlatformView;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
Expand All @@ -60,6 +62,7 @@ final class GoogleMapController
OnMapReadyCallback,
GoogleMap.OnMapClickListener,
GoogleMap.OnMapLongClickListener,
GoogleMap.SnapshotReadyCallback,
PlatformView {

private static final String TAG = "GoogleMapController";
Expand Down Expand Up @@ -220,6 +223,11 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) {
}
break;
}
case "map#snapshot":
{
googleMap.snapshot(this);
break;
}
case "camera#move":
{
final CameraUpdate cameraUpdate =
Expand Down Expand Up @@ -403,6 +411,15 @@ public void onCircleClick(Circle circle) {
circlesController.onCircleTap(circle.getId());
}

@Override
public void onSnapshotReady(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
bitmap.recycle();
methodChannel.invokeMethod("map#onSnapshot", byteArray);
}

@Override
public void dispose() {
if (disposed) {
Expand Down
39 changes: 39 additions & 0 deletions packages/google_maps_flutter/example/lib/map_ui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:flutter/services.dart' show rootBundle;
Expand Down Expand Up @@ -186,6 +189,14 @@ class MapUiBodyState extends State<MapUiBody> {
);
}

Widget _snapshotter() {
return FlatButton(
child: const Text('make snapshot'),
onPressed: () {
_controller.snapshot();
});
}

Future<String> _getFileData(String path) async {
return await rootBundle.loadString(path);
}
Expand Down Expand Up @@ -232,6 +243,7 @@ class MapUiBodyState extends State<MapUiBody> {
myLocationEnabled: _myLocationEnabled,
myLocationButtonEnabled: _myLocationButtonEnabled,
onCameraMove: _updateCameraPosition,
onSnapshot: _snapshot,
);

final List<Widget> columnChildren = <Widget>[
Expand Down Expand Up @@ -269,6 +281,7 @@ class MapUiBodyState extends State<MapUiBody> {
_zoomToggler(),
_myLocationToggler(),
_myLocationButtonToggler(),
_snapshotter(),
_nightModeToggler(),
],
),
Expand All @@ -289,9 +302,35 @@ class MapUiBodyState extends State<MapUiBody> {
}

void onMapCreated(GoogleMapController controller) {
_controller = controller;
setState(() {
_controller = controller;
_isMapCreated = true;
});
}

void _snapshot(Uint8List argument) async {
final ui.Codec codec = await ui.instantiateImageCodec(argument);
final ui.FrameInfo frame = await codec.getNextFrame();
final ui.Image img = frame.image;
print('${argument.length} bytes, ${img.width} x ${img.height} px');
await showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
actions: <Widget>[
FlatButton(
child: const Text('OK'),
onPressed: () => Navigator.of(context).pop(),
)
],
content: Padding(
padding: const EdgeInsets.symmetric(vertical: 66),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[Image.memory(argument)],
)));
},
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ - (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
} else if ([call.method isEqualToString:@"map#update"]) {
InterpretMapOptions(call.arguments[@"options"], self);
result(PositionToJson([self cameraPosition]));
} else if ([call.method isEqualToString:@"map#snapshot"]) {
UIGraphicsBeginImageContext(_mapView.frame.size);
[_mapView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage* screenShotImage = UIGraphicsGetImageFromCurrentImageContext();
NSData* imageData = UIImagePNGRepresentation(screenShotImage);
[_channel invokeMethod:@"map#onSnapshot" arguments:imageData];
UIGraphicsEndImageContext();
result(nil);
} else if ([call.method isEqualToString:@"map#getVisibleRegion"]) {
if (_mapView != nil) {
GMSVisibleRegion visibleRegion = _mapView.projection.visibleRegion;
Expand Down
8 changes: 8 additions & 0 deletions packages/google_maps_flutter/lib/src/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ class GoogleMapController {
_googleMapState
.onLongPress(LatLng._fromJson(call.arguments['position']));
break;
case 'map#onSnapshot':
_googleMapState.onSnaphot(call.arguments);
break;
default:
throw MissingPluginException();
}
Expand Down Expand Up @@ -204,4 +207,9 @@ class GoogleMapController {

return LatLngBounds(northeast: northeast, southwest: southwest);
}

/// Ask for a snapshot to be returned via onSnapshot event
Future<void> snapshot() async {
await channel.invokeMethod<void>('map#snapshot');
}
}
11 changes: 11 additions & 0 deletions packages/google_maps_flutter/lib/src/google_map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class GoogleMap extends StatefulWidget {
this.onCameraIdle,
this.onTap,
this.onLongPress,
this.onSnapshot,
}) : assert(initialCameraPosition != null),
super(key: key);

Expand Down Expand Up @@ -112,6 +113,9 @@ class GoogleMap extends StatefulWidget {
/// Called every time a [GoogleMap] is long pressed.
final ArgumentCallback<LatLng> onLongPress;

/// Called when a snapshot has completed
final ArgumentCallback<Uint8List> onSnapshot;

/// True if a "My Location" layer should be shown on the map.
///
/// This layer includes a location indicator at the current device location,
Expand Down Expand Up @@ -328,6 +332,13 @@ class _GoogleMapState extends State<GoogleMap> {
widget.onLongPress(position);
}
}

void onSnaphot(Uint8List imgData) {
assert(imgData != null);
if (widget.onSnapshot != null) {
widget.onSnapshot(imgData);
}
}
}

/// Configuration options for the GoogleMaps user interface.
Expand Down