Friday, November 7, 2008

Saving Map Snapshot

This week, while in Redlands for a holistic lab session on the Flex API for ArcGIS Server, a user showed me the following gem. Using the new Flash Player 10 FileReference class, you can create an image snapshot of a map component and save it locally to a file, without a server side service. To compile the application using FlexBuilder, you need to adjust your compiler SDK to version 3.2.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:esri="http://www.esri.com/2008/ags"
layout="vertical"
>
<mx:Script>
<![CDATA[
import mx.graphics.ImageSnapshot;
import mx.graphics.codec.JPEGEncoder;

private function clickHandler() : void
{
const decoder: JPEGEncoder = new JPEGEncoder();
map.logoVisible=false;
map.scaleBarVisible=false;
map.zoomSliderVisible = false;
const imageSnapshot:ImageSnapshot = ImageSnapshot.captureImage(map,96,decoder,true);
map.logoVisible=true;
map.scaleBarVisible=true;
map.zoomSliderVisible = true;
const fileReference:FileReference = new FileReference();
fileReference.save(imageSnapshot.data,"map.jpg");
}
]]>
</mx:Script>
<esri:Map id="map">
<esri:ArcGISTiledMapServiceLayer
url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
</esri:Map>
<mx:Button label="Snapshot" click="clickHandler()"/>
</mx:Application>

Thanks Ofir :-)

13 comments:

Isa said...
This comment has been removed by the author.
Isa said...

Your code was a great help. I wanted to know if this scenario is possible:
I need to capture the image of an application under test but I don't want to be prompted by the file save dialog. Can it be somehow done silently through code? I checked out the FileReference.save() method for options, but it doesn't have the facility to prevent the file dialog box from popping up.
Any ideas? All help will be appreciated! Thanks.

thunderhead said...

This is a security measure in FP10 - sorry ! you can switch to AIR and it will not prompt you :-)

Isa said...

Oh ok! Thanks for your quick response. Actually I need to do this for web apps so can't change it to AIR. All the other examples I saw on the net save the img file on the server and then download it, which is not feasible. Is there any other option then for saving a file locally except for FileReference.save() ? Thanks for your time!

thunderhead said...

Sorry - not that I am aware of :-(

Manolo Frias said...

Hi,

is it possible to export it to others formats, e.g. svg? According to the Flex Reference mx.graphics.codec contains only jpg and png but I wonder if you know any workaround.

Thanks!
Manolo

Unknown said...

Hi Mansour,
I have captured image from map object and put captured image in image control but when I tried to print this image, I have found distortion in the image.

I need to save image without distortion.

Note: image control has width and height.

//this is sample code

var bitmapData:BitmapData = ImageSnapshot.captureBitmapData(map);
var encoder:JPEGEncoder = new JPEGEncoder(100);
var bytes:ByteArray = encoder.encode(bitmapData);
imgControl.load(bytes);

Thanks,
Khalid Mohie

thunderhead said...

Eh...what kind of distortions u r finding ? I mean, after all, this is just a snapshot - u can scale it down - but if u stretch it - then u will see distortions.

cp1436 said...

will it also capture the GraphicsLayer in the map?

thunderhead said...

Yes it does :-)

Unknown said...

I think this will help in what I am trying to do but I know just enough about flex to be dangerous. Were do I put this code to get it into my application? Right now I made a new mxml application but I am missing something.

Unknown said...

Hi Mansour,

Great help. But do you have a recommendation how to save a map snapshot if the ArcGIS Server Map is embedded in a Flex Frontend we have no access to, but want to create the snapshot with option of the REST API? How could that work? How would we need to address the service /active map window with REST and create and save a snapshot?

BR

thunderhead said...

Can u do it at the JavaScript level ? maybe using something like http://html2canvas.hertzen.com/ ?