How do I add exif data to an image in AS3? - actionscript-3

How do I add exif data to a JPG or PNG in AS3?
var x:JPEGEncoderOptions = new JPEGEncoderOptions();
var jpegEncoder:JPEGEncoder = new JPEGEncoder(100);
var bitmapData:BitmapData = new BitmapData(100,100,true,0x00000000);
bitmapData.drawWithQuality(this);
var ba:ByteArray = jpegEncoder.encode(bitmapData);
var file:FileReference = new FileReference();
file.save(ba, "ScreenShot.jpeg");
More info
In my app we are letting the user take a screen shot using the PNGEncoder and JPEGEncoder class. They've asked to be able to save the Author creation date and time in Exif. I'm able to create the bytearray and then save that file but I don't know how to add the exif data to it.

Related

How to take a snapshot of a chart and save into Byte Array in flex?

I'm trying to capture snapshot of a chart and save that image as a Byte Array in flex. currently i'm using this method to save a snapshot but now i want to save image in a Byte array. Is this possible ?
this is my current method
private function takeSnapshot():void{
var image:ImageSnapshot = ImageSnapshot.captureImage(chart);
var file:FileReference = new FileReference();
var fileName:String = "chart.png";
file.save(image.data,fileName);
This is how I would do in AS3:
// displayObject being the object to render
var data:BitmapData = new BitmapData(displayObject.width, displayObject.height, true, 0);
data.draw(displayObject);
// the you can have either a raw bytearray or a png:
var bitmapBa:ByteArray = data.getPixels( new Rectangle(0, 0, displayObject.width, displayObject.height);
// or if you're saving to PNG:
var pngBA:ByteArray = PNGEncoder.encode( data );

Flex Mobile AS3, PersistenceManager storing/receiving BitmapData

I'm using the PersistenceManager to store data from my App. If I store BitmapData, it will stored correctly, but after a restart the BitmapData is now an Object. If I cast the Object to BitmapData it doesn't work.
pm.setProperty("sign", signArea.getBitmapData());
And this is the way I try to load it.
pm.getProperty("sign") as BitmapData;
If I doesn't stop the app, it would loaded correctly, but after a restart the "sign" is not BitmapData anymore. It's now an Object.
I don't think you can safely store an instance of BitmapData in a shared object (internally used in the PersistanceManager). It is not explicitly mentioned in the docs: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/SharedObject.html
You can however save the data of the BitmapData as a ByteArray and convert is back when retrieving.
// write
var byteArray:ByteArray = bitmap.bitmapData.getPixels(bitmap.bitmapData.rect);
so.data.byteArray = byteArray;
so.data.width = bitmap.bitmapData.rect.width;
so.data.height = bitmap.bitmapData.rect.height;
so.flush();
// read
var byteArray:ByteArray = so.data.byteArray;
var bitmapData:BitmapData = new BitmapData(so.data.width, so.data.height);
bitmapData.setPixels(bitmapData.rect, byteArray);
Notice that you'll also need to store the width and the height of the image. You could wrap this in an object so that you have 1 entry in the persistance manager instead of 3. This might be more convenient if you want to store multiple bitmaps.
// write
var bd:BitmapData = signArea.getBitmapData();
var r:Rectangle = bd.rect;
pm.setProperty("sign", {bytes:bd.getPixels(r), width:r.width, height:r.height});
// read
var signData:Object = pm.getProperty("sign");
var bitmapData:BitmapData = new BitmapData(signData.width, signData.height);
bitmapData.setPixels(bitmapData.rect, signData.bytes);

Loading an Image with AIR and Displaying It On Stage

I am having trouble loading an image and displaying it on stage using the File API in as3. I am able to successfully load it in but when I put it on stage the image is just noise. I am assuming because I need to decode the PNG/JPG into Bitmap data somehow and I am doing it wrong? Here is my code:
public function browseForIcon(){
var file:File = new File();
file.addEventListener(Event.SELECT, onFileSelected);
file.browseForOpen("Select a an image");
}
private function onFileSelected(event:Event):void {
var stream:FileStream = new FileStream();
stream.open(event.target as File, FileMode.READ);
var bytes:ByteArray = new ByteArray();
stream.readBytes(bytes);
var img = new BitmapData(160,160);
img.setPixels(new Rectangle(0,0,160,160),bytes);
this.addChild(new Bitmap(img));
}
}
THANKS!
One option is to use Loader.loadBytes(). If you're using Flex, you could also use an Image with source set to the File.

Save JPG from CDROM to PC

I am using following function to Save the output from SWF and send it to a PHP page so that it creates JPG, my problem if there is not INTERNET connection and the SWF is in a CDROM can the Save function be used in FLASH so that it outputs JPG and save it on a computer.
In short can we Save movieclip output as an JPG
/**
Screenshot and jpg output
**/
import flash.display.BitmapData;
import flash.geom.Matrix;
//Buttons handlers. Should add an extra function because delegate doesn't allow to pass parameters
shaF.onPress = mx.utils.Delegate.create(this,makeShadow);
//Helper functions to pass parameters
function makeShadow() { capture(0) }
/*
create a function that takes a snapshot of the Video object whenever it is called
and shows in different clips
*/
function capture(nr){
this["snapshot"+nr] = new BitmapData(abc._width,abc._height);
//the bitmap object with no transformations applied
this["snapshot"+nr].draw(abc,new Matrix());
var t:MovieClip = createEmptyMovieClip("bitmap_mc"+nr,nr);
//positions clip in correct place
//t._x = 350; t._y = 10+(nr*130); t._xscale = t._yscale = 50
//display the specified bitmap object inside the movie clip
t.attachBitmap(this["snapshot"+nr],1);
output(nr);
//attachMovie("print_but", "bot"+nr, 100+nr, {_x:t._x+t._width+50, _y:t._y+t._height/2})
}
//Create a new bitmapdata, resize it 50 %, pass image data to a server script
// using a LoadVars object (large packet)
function output(nr){
//Here we will copy pixels data
var pixels:Array = new Array()
//Create a new BitmapData
var snap = new BitmapData(this["snapshot"+nr].width, this["snapshot"+nr].height);
//Matrix to scale the new image
myMatrix = new Matrix();
myMatrix.scale(1, 1)
//Copy image
snap.draw(this["snapshot"+nr], myMatrix);
var w:Number = snap.width, tmp
var h:Number = snap.height
//Build pixels array
for(var a=0; a<=w; a++){
for(var b=0; b<=h; b++){
tmp = snap.getPixel32(a, b).toString(16)
//if(tmp == "-fcffff")
//{
//tmp="-ff0000";
//}
pixels.push(tmp.substr(1))
}
}
//Create the LoadVars object and pass data to PHP script
var output:LoadVars = new LoadVars()
output.img = pixels.toString()
output.height = h
output.width = w
//The page (and this movie itself) should be in a server to work
output.send("show.php", "output", "POST")
}
stop()
Since you already have the BitmapData, this is fairly easy. Modifying your output function:
//Copy image
snap.draw(this["snapshot"+nr], myMatrix);
//Now check if we want to save as JPG instead of sending data to the server
if (runningFromCdrom) {
var encoder:JPEGEncoder = new JPEGEncoder();
var bytes:ByteArray = encoder.encode(snap);
var file:FileReference = new FileReference();
file.save(bytes);
} else {
// ...the rest of your output method...
}
How to determine the runningFromCdrom value is up to you. If the SWF is being run inside an HTML document, the best way to tell if the program is being run from a CD-ROM would be to specify it in the FlashVars.
Yes, you can save JPEG's directly from Flash. There is no need for the intermediate step to PHP.
You can use one of these JPEG encoders:
https://github.com/mikechambers/as3corelib
http://www.switchonthecode.com/tutorials/flex-tutorial-an-asynchronous-jpeg-encoder
I would recommend the second as it can work asynchronously (kind of) which means your UI shouldn't lock up while encoding the JPEG.

Action Script 3, Graph API - Load Facebook avatar, then use JPGEncoder to save image

im trying to load my facebook display image and then save it through as3 using JPGEncoder.
Right now im getting the image url and through a Loader, adding the image to a movie clip called foto1. This is working fine:
var image:URLRequest = new URLRequest("http://graph.facebook.com/" + response[0].id + "/picture?type=large");
imageLoader.load(
foto1.addChild(imageLoader);
The problem is when i try this:
var myImage:Bitmap;
var jpgSource:BitmapData = new BitmapData (foto1.width, foto1.height);
jpgSource.draw(foto1);
var jpgEncoder:JPGEncoder = new JPGEncoder(n);
var jpgStream:ByteArray = jpgEncoder.encode(jpgSource);
var header:URLRequestHeader = new URLRequestHeader ("Content-type", "application/octet-stream");
//Make sure to use the correct path to jpg_encoder_download.php
var jpgURLRequest:URLRequest = new URLRequest ("http://www.thewebchi.mp/pruebas_graph/download.php?name=" + fileName + ".jpg");
jpgURLRequest.requestHeaders.push(header);
jpgURLRequest.method = URLRequestMethod.POST;
jpgURLRequest.data = jpgStream;
var loader:URLLoader = new URLLoader();
navigateToURL(jpgURLRequest, "_blank");
If i try the jpg process on movie clip 'foto1' without loading the external image, it works fine.
When i load the image to 'foto1' the jpg process doesnt respond.
Thank you very much!!!
Is it necessary to use navigateToURL (opening in the browser window)? If not, I would suggest using the URLLoader, loader.load(jpgURLRequest). Also, using this approach you can listen for IOErrorEvent.IO_ERROR on the loader (and other events) that may give you some hints on what is wrong.