Avg. Rating 4.3

Problem

We need to take a screenshot from some interface element and submit it to server-side code.

Solution

Every interface element implementing flash.display.IBitmapDrawable programmic interface can be screened using ImageSnapshot.captureBitmapData(). Next step is to cover obtained BitmapData to jpg-containing ByteArray using JPGEncoder(), code it to string with Base64Encoder() and transfer to server in URLLoader's request data property.

Detailed explanation

Let's imagine a situation when we need to submit to server some user element screenshot (site preview in cms, user record in online game with client-side logic ets.). And, more over, we should form proper .jpg file. We should do it without any user action – no dialog boxes or smth. And, in additional, we have scanty server ability – so,only way to do it is to put it in some request. Sounds sad, isn't it? But read this acticle and You will look at it more optimistic.

So, let's start. We have a Canvas() instance named targetCanvas. Canvas() implementing IbitmapDrawable interface so we can take it's screen like follows (all visible targetCanvas child will be on this screenshot, with coressponding effects and filters):

var siteScreenBitmapData:BitmapData = ImageSnapshot.captureBitmapData(targetCanvas);

 

Then, if we should obtain image with concrete width and height (150x200 in our example) we should transform obtained data:


 

var sizeMatrix:Matrix = new Matrix();

var coef:Number = Math.min(200/siteScreenBitmapData.width,150/siteScreenBitmapData.height);

sizeMatrix.a = coef;

sizeMatrix.d = coef;

siteScreenBitmapData =ImageSnapshot.captureBitmapData(targetCanvas,sizeMatrix);

 

Put your attemtion on fact we re-capture BitmapData from same targetCanvas source but using matrix with coefficients we exactly need.
 

Next step is to cover our bitmap data to fully proper formatted jpg image. We will use JPGEncoder() (in this example used class frm Adobe corelib, if you using sdk 3.2 or higher – use standard):

 

var jec:JPGEncoder = new JPGEncoder();

var ba:ByteArray = jec.encode(siteScreenBitmapData);

 

So, now we have ByteArray with jpg file in it. If your backend allows WSDL connection You can send it directly to server methods just now – as ByteArray (server method should just to save it into file). But in our case we have mentioned restriction – we can use requests only. So, let's the magic start!

Convert ByteArray to Strng() via Base64 algorithm (with encoder class same situation as with JPGEncoder):

 

var coder:Base64Encoder = new Base64Encoder();

coder.encodeBytes(ba , 0 , ba.length);

var imString:String = coder.toString();

And last step – add obtained string to request data:

var cmd : XML = <cmd type="save" />;

var scmd : XML = <preview>{imString}</preview>;

cmd.appendChild(scmd);


 

var req : URLRequest = new URLRequest(“Here_URI”);

req.data = cmd.toXMLString();

req.method = URLRequestMethod.POST;

req.contentType = "text/xml";

var loader : URLLoader = new URLLoader(req);

//Here assign corresponding listeners to loader

loader.load(req);

 

As a result we've obtained URLLoader with requst containing our image in it's data – how it's time for becked guys to work, we've done everithing best.

 

Whole example listening here:

 

var siteScreenBitmapData:BitmapData = ImageSnapshot.captureBitmapData(targetCanvas);

 

var sizeMatrix:Matrix = new Matrix();

var coef:Number = Math.min(200/siteScreenBitmapData.width,150/siteScreenBitmapData.height);

sizeMatrix.a = coef;

sizeMatrix.d = coef;

siteScreenBitmapData =ImageSnapshot.captureBitmapData(targetCanvas,sizeMatrix);

 

var jec:JPGEncoder = new JPGEncoder();

var ba:ByteArray = jec.encode(siteScreenBitmapData);

var coder:Base64Encoder = new Base64Encoder();

coder.encodeBytes(ba , 0 , ba.length);

var imString:String = coder.toString();

var cmd : XML = <cmd type="save" />;

var scmd : XML = <preview>{imString}</preview>;

cmd.appendChild(scmd);


 

var req : URLRequest = new URLRequest(“Here_URI”);

req.data = cmd.toXMLString();

req.method = URLRequestMethod.POST;

req.contentType = "text/xml";

var loader : URLLoader = new URLLoader(req);

loader.load(req);

Report abuse

Related recipes