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:

  1. This comment has been removed by the author.

    ReplyDelete
  2. 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.

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

    ReplyDelete
  4. 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!

    ReplyDelete
  5. Sorry - not that I am aware of :-(

    ReplyDelete
  6. 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

    ReplyDelete
  7. 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

    ReplyDelete
  8. 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.

    ReplyDelete
  9. will it also capture the GraphicsLayer in the map?

    ReplyDelete
  10. 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.

    ReplyDelete
  11. 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

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

    ReplyDelete