Image overlays can be used to quickly render frequently changing images in a map view or scene view. For example, you can render real-time sensor data, such as weather, where each static image displayed represents a single frame from the radar satellite image. A user perceives the display of the static images in succession as an animation if the images are displayed at small enough time intervals.
Image overlays and graphics overlays both render above all layers in the map or scene. Image overlays render below any graphics overlays you've added to the view. This order ensures that graphics you want to display won't be obscured by your image overlays. For example, you might want to show graphics representing aircraft on top of image overlays showing the sensor data they are collecting.
Since they are designed for quick display, image overlays do not support the rich processing and rendering capabilities of a raster layer, which still provides the best option for workflows that require static image rendering, analysis, and persistence. See Add raster data for more information about working with raster layers.
Add an image overlay
A map or scene view manages a collection of image overlays. Each ImageOverlay
contains a single ImageFrame
that defines an image to display. Georeferenced images (those with a world file) are added at the correct geographic location. Otherwise, you must define a geographic extent for the image frame. If a spatial reference is not defined for the extent, it is assumed to be the same as the map or scene. If the spatial reference of the extent is different from that of the map or scene, the image will fail to render.
-
If your image doesn't have georeference information, define an extent for the image using an
Envelope
or quadrilateralPolygon
.Create envelopeUse dark colors for code blocks Copy // An envelope of the Pacific sector in southwest // US for displaying the image frame. final pacificSouthwestEnvelope = Envelope.fromCenter( ArcGISPoint( x: -120.0724273439448, y: 35.131016955536694, spatialReference: SpatialReference.wgs84, ), width: 15.09589635986124, height: -14.3770441522488, );
You can also define a geographic extent using a polygon that has exactly four points (to define each corner of the image). The polygon can be any quadrilateral; it need not be a rectangle.
Create polygonUse dark colors for code blocks Copy // (untransformed) Lower-left -> Upper-left -> Upper-right -> Lower-right. final polygonGeometry = PolygonBuilder(spatialReference: SpatialReference.wgs84) ..addPoint(ArcGISPoint(x: -123, y: 27)) ..addPoint(ArcGISPoint(x: -123, y: 40)) ..addPoint(ArcGISPoint(x: -120, y: 40)) ..addPoint(ArcGISPoint(x: -120, y: 27)); final pacificSouthwestPolygon = polygonGeometry.toGeometry();
When you define the polygon, the order in which you specify the vertices has significance and can result in rotating or reflecting the image displayed within the polygon.
In the following descriptions, all starting positions refer to the original (untransformed) position.
When specifying vertices in the clockwise direction: Start in the lower-left corner to display the image in its original orientation. Starting at the next clockwise vertex rotates the image 90° clockwise, and so on.
When specifying vertices in the counterclockwise direction: Start in the lower-right corner to reflect the image around the y-axis. Starting at the next counterclockwise vertex rotates the reflected image 90° counterclockwise, and so on.
-
Create an image frame and pass an
ArcGISImage
into the constructor. These formats are supported forArcGIS
: TIFF, GeoTIFF, ICO, BMP, GIF, JPEG, and PNG. Animated GIF is not supported. If you need to define the extent explicitly, also pass the envelope or polygon to the constructor.Image Create image frame using ArcGISImageUse dark colors for code blocks Copy // Create an image frame with a path to a local file to a supported // ArcGIS image and an extent. // The image file list represents a list of files storing the Uri // to each local image. final frame = ImageFrame.withImageEnvelope( image: ArcGISImage.fromFile(imageFileList[index].uri)!, extent: pacificSouthwestEnvelope, );
Create image frame using UriUse dark colors for code blocks Copy // Create an image frame by passing the Uri to a local file path // or an online (HTTP) path to an image. final frame = ImageFrame.withUri(uri);
-
Attach the initial image frame to the image overlay. The image overlay has properties to control visibility and opacity of the image. Set the opacity less than 1.0 to make the image semi-transparent so data underneath can be seen.
Create image frame using UriUse dark colors for code blocks Copy // Wait for the frame to load. await frame.load(); // Add the image frame to an image overlay // and set it to be 50% transparent. imageOverlay.imageFrame = frame; imageOverlay.opacity = 0.5;
-
Add the image overlay to the map or scene view's image overlay collection. To zoom to the extent of the image, you can set the viewpoint using the image frame extent.
Add image overlay to ArcGIS scene view controller's image overlay collectionUse dark colors for code blocks Copy // Add image overlay to ArcGIS scene view controller's // image overlay collection. sceneViewController.imageOverlays.add(imageOverlay);
Set viewpoint with the image frame's extentUse dark colors for code blocks Copy // Set the camera position and orientation. // The camera is positioned over the Pacific South West region. final camera = Camera.withLocation( location: ArcGISPoint( x: -116.621, y: 24.7773, z: 856977, spatialReference: SpatialReference.wgs84, ), heading: 353.994, pitch: 48.5495, roll: 0, ); sceneViewController.setViewpointCamera(camera);

Animate an image overlay
You can animate the display of image overlays by changing the frame they contain at a specified interval. You might use a timer, for example, to read the next image in a sequence, use it to create a new ImageFrame
, and replace the current frame in the ImageOverlay
.
-
Create a function that sets the image frame to the image overlay based on the index.
Set the image frame to the image overlay based on the indexUse dark colors for code blocks Copy // Sets the image frame to the image overlay based on the index. void setImageFrame(int index) async { // Create an image frame with a path to a local file to a supported // ArcGIS image and an extent. // The image file list represents a list of files storing the Uri // to each local image. final frame = ImageFrame.withImageEnvelope( image: ArcGISImage.fromFile(imageFileList[index].uri)!, extent: pacificSouthwestEnvelope, ); // Wait for the frame to load. await frame.load(); // Set the image overlay frame. imageOverlay.imageFrame = frame; }
-
Create an image animation ticker and set it to call a function to change the image animation once per animation frame.
Start the image animation tickerUse dark colors for code blocks Copy // Start the image animation ticker. This function can // be tied to user interface to start the animation. void startTicker() { _lastFrameTime = 0; // Create a ticker to control the image frame animation. _ticker = _ticker ?? createTicker(_onTicker); // Start the ticker. _ticker!.start(); // App status to track when the animation is started. setState(() => _started = true); }
-
For each callback, once per animation frame, call the
set
function to replace the current image frame in the overlay with the next image frame from the list.Image Frame(index) A function to change the image frame.Use dark colors for code blocks Copy // Callback function for the ticker to change the image frame. void _onTicker(Duration elapsed) { // Determine the elapsed time since the animation was updated. final delta = elapsed.inMilliseconds - _lastFrameTime; // Determine if enough time has passed a predetermined speed (in milliseconds). if (delta >= _imageFrameSpeed) { // Get the index for the next overlay image. _imageFrameIndex = (_imageFrameIndex + 1) % imageFileList.length; // Call function to change the current image frame to the next one. setImageFrame(_imageFrameIndex); // Update the time after the next image frame is set. _lastFrameTime = elapsed.inMilliseconds; } }