I'm using the AS3 code below to take a photo throught the cameraUI. Everything works fine on the Android but when I test on the iPad I get an error when trying to load the saved image. The ioErrorHandler1 returns:
ioErrorHandler: [IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2124: Loaded file is an unknown type. URL: app-storage:/myImage.jpg" errorID=2124]
Anyone know why? (as mentioned it works on Android). Here's the code:
function imageCaptured( event:MediaEvent ):void
{
trace( "Media captured..." );
var imagePromise:MediaPromise = event.data;
dataSource = imagePromise.open();
if( imagePromise.isAsync )
{
trace( "Asynchronous media promise." );
eventSource = dataSource as IEventDispatcher;
imageLoader = new Loader();
imageLoader.contentLoaderInfo.addEventListener( Event.COMPLETE, asyncImageLoaded );
imageLoader.addEventListener( IOErrorEvent.IO_ERROR, cameraError );
imageLoader.loadFilePromise( imagePromise );
}
else
{
trace( "Synchronous media promise." );
imageLoader.loadFilePromise( imagePromise );
showMedia( imageLoader );
}
}
function asyncImageLoaded( event:Event ):void
{
readMediaData();
}
function readMediaData():void
{
var image:Bitmap = Bitmap(imageLoader.content);
var bitmap:BitmapData = image.bitmapData;
image.width = 100;
image.height = 100;
this.addChild(image);
var imageBytes:ByteArray = new ByteArray();
dataSource.readBytes( imageBytes );
var file:File = File.applicationStorageDirectory.resolvePath("myImage.jpg");
// create a file stream
var fs:FileStream=new FileStream();
// open the stream for writting
fs.openAsync(file, FileMode.WRITE);
// write the string data down to the file
fs.writeBytes(imageBytes);
// ok close the file stream
fs.close();
fs.addEventListener(Event.CLOSE,function(event:Event):void {
var mLoader=new Loader();
var mRequest:URLRequest = new URLRequest(file.url);
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, function (event:Event):void{
showMediaLoad(mLoader);
});
mLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler1);
mLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
mLoader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
mLoader.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
mLoader.load(mRequest);
})
trace("saved");
}
You might need to encode your ByteArray before saving it as a jpeg.
Here's a snippet of code I used a while back...
import com.adobe.images.JPGEncoder;
private var f:File;
private var stream:FileStream;
private var j:JPGEncoder;
private var image:Bitmap = Bitmap(imageLoader.content);
private var urlRequest:URLRequest;
private var loader:Loader;
function saveImage():void {
f = File.documentsDirectory.resolvePath("logo.jpg");
stream = new FileStream();
stream.open(f, FileMode.WRITE);
j = new JPGEncoder(80);
var bytes:ByteArray = j.encode(image.bitmapData);
stream.writeBytes(bytes, 0, bytes.bytesAvailable);
stream.close();
stream.openAsync(f, FileMode.READ);
stream.addEventListener(Event.COMPLETE, loadImage, false, 0, true);
}
private function loadImage(e:Event):void {
stream.removeEventListener(Event.COMPLETE, loadImage);
stream = null;
//now load the image
if (f.exists == true) {
urlRequest = new URLRequest(f.url);
loader = new Loader;
loader.load(urlRequest);
loader.addEventListener(IOErrorEvent.IO_ERROR, function(e:IOErrorEvent):void{ trace(e) });
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, ImageLoaded, false, 0, true);
}
}
private function ImageLoaded(e:Event):void {
addChild(loader);
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, ImageLoaded);
}
I found a solution. It works without jpgencoder if I put an eventlistener on the eventSource. I'm posting it here if anyone else could use the solution:
The imageCaptured function is updated like this:
if( imagePromise.isAsync )
{
trace( "Asynchronous media promise." );
var eventSource:IEventDispatcher = dataSource as IEventDispatcher;
eventSource.addEventListener( Event.COMPLETE, onMediaLoaded );
}
And then the image is save in this function:
function onMediaLoaded( event:Event ):void
{
trace("Media load complete");
var imageBytes:ByteArray = new ByteArray();
dataSource.readBytes( imageBytes );
var file:File = File.applicationStorageDirectory.resolvePath("myImage.jpg");
// create a file stream
var fs:FileStream=new FileStream();
// open the stream for writting
fs.openAsync(file, FileMode.WRITE);
// write the string data down to the file
//fs.writeBytes(imageBytes);
fs.writeBytes(imageBytes);
// ok close the file stream
fs.close();
fs.addEventListener(Event.CLOSE, function(e:Event):void {
var mLoader=new Loader();
var mRequest:URLRequest = new URLRequest(file.url);
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, function (event:Event):void{
showMediaLoad(mLoader);
});
mLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler1);
mLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
mLoader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
mLoader.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
mLoader.load(mRequest);
}
Related
I want to make a basic example Firefox add-on using js-ctype. First, I made a .dll file with a simple C code:
#include "stdio.h"
extern "C"
{
__declspec(dllexport) int add(int a, int b) { return a + b; }
}
The library file is fine. I tested it in another project.
I load it by js-ctypes code:
var {Cu , Cc, Ci} = require("chrome");
Cu.import("resource://gre/modules/ctypes.jsm", null);
Cu.import("resource://gre/modules/Services.jsm");
var self = require("sdk/self");
var prompts = Cc["#mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
var dataUrl = self.data.url("Js-CtypeLib.dll");
dataUrl = Services.io.newURI(dataUrl,null,null).QueryInterface(Ci.nsIFileURL).file.path;
var lib, add;
try{
console.log("Load library");
lib = ctypes.open("Js-CtypeLib.dll");
try{
declareFunc();
}
catch(e){
console.log("Error declare function");
}
}
catch(e){
console.log("Error load Library!");
}
function declareFunc(){
add = lib.declare("add", ctypes.default_abi, ctypes.int, ctypes.int, ctypes.int);
}
function test(){
var rs = add(4,2);
prompts.alert(null, "Result: ", rs);
lib.close();
}
exports.test = test;
and then, I call support.js file by index.js
var buttons = require('sdk/ui/button/action');
var tabs = require("sdk/tabs");
var support = require("./support.js");
var button = buttons.ActionButton({
id: "mozilla-link",
label: "Visit Mozilla",
icon: {
"16": "./images/icon-16.png",
"32": "./images/icon-32.png",
"64": "./images/icon-64.png"
},
onClick: handleClick}
);
function handleClick(state) {
support.test();
}
Finally, in cmd, I run it and get:
Component returned failure code: 0x80004002 (NS_NOINTERFACE) [nsIFileURL.file]
Full error text:
You need to mark your addon as "unpacked" in the package.json. Then you must use a file:// uri in the call to ctypes.open(file_uri_here).
To get a file uri of a file in your addon you would do this:
Components.utils.import("resource://gre/modules/Services.jsm");
var cr = Components.classes['#mozilla.org/chrome/chrome-registry;1'].getService(Components.interfaces.nsIChromeRegistry);
var chromeURI_myLib = Services.io.newURI('chrome://youraddon/content/mySubFolder/myCFunctionsForUnix.so', 'UTF-8', null);
var localFile_myLib = cr.convertChromeURL(chromeURI_myLib);
var jarPath_myLib = localFile_myLib.spec; // "jar:file:///C:/Users/Vayeate/AppData/Roaming/Mozilla/Firefox/Profiles/aecgxse.Unnamed%20Profile%201/extensions/youraddon#jetpack.xpi!/mySubFolder/myCFunctionsForUnix.so"
var filePath_myLib = localFilemyLib.path;
ctypes.open(filePath_myLib);
I've seen this question asked here already : Web Audio API Memory Leaks on Mobile Platforms but there doesn't seem to be any response to it. I've tried lots of different variations - setting variables to null once I'm finished with them, or declaring the variables within scope, but it appears that the AudioContext (or OfflineAudioContext ) is not being Garbage collected after each operation. I'm using this with Phonegap, on an IOS, so the browser is safari. Any ideas how to solve this memory leak?
Here is my code:
function readVocalsToBuffer(file){
console.log('readVocalsToBuffer');
var reader = new FileReader();
reader.onloadend = function(evt){
var x = audioContext.decodeAudioData(evt.target._result, function(buffer){
if(!buffer){
console.log('error decoding file to Audio Buffer');
return;
}
window.voiceBuffer = buffer;
loadBuffers();
});
}
reader.readAsArrayBuffer(file);
}
function loadBuffers(){
console.log('loadBuffers');
try{
var bufferLoader = new BufferLoader(
audioContext,
[
"."+window.srcSong
],
createOffLineContext
);
bufferLoader.load()
}
catch(e){
console.log(e.message);
}
}
function createOffLineContext(bufferList){
console.log('createOfflineContext');
offline = new webkitOfflineAudioContext(2, window.voiceBuffer.length, 44100);
var vocalSource = offline.createBufferSource();
vocalSource.buffer = window.voiceBuffer;
vocalSource.connect(offline.destination);
var backing = offline.createBufferSource();
backing.buffer = bufferList[0];
backing.connect(offline.destination);
vocalSource.start(0);
backing.start(0);
offline.oncomplete = function(ev){
vocalSource.stop(0);
backing.stop(0);
vocalSource.disconnect(0);
backing.disconnect(0);
delete vocalSource;
delete backing;
delete window.voiceBuffer;
window.renderedFile = ev.renderedBuffer;
var bufferR = ev.renderedBuffer.getChannelData(0);
var bufferL = ev.renderedBuffer.getChannelData(1);
var interleaved = interleave(bufferL, bufferR);
var dataview = encodeWAV(interleaved);
window.audioBlob = new Blob([dataview], {type: 'Wav'});
saveFile();
}
offline.startRendering();
}
function interleave(inputL, inputR){
console.log('interleave');
var length = inputL.length + inputR.length;
var result = new Float32Array(length);
var index = 0,
inputIndex = 0;
while (index < length){
result[index++] = inputL[inputIndex];
result[index++] = inputR[inputIndex];
inputIndex++;
}
return result;
}
function saveFile(){
offline = null;
console.log('saveFile');
delete window.renderedFile;
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFSSuccess, fail);
}
**I have an air app for iOS I have been developing. I am trying to capture a picture, save the file to the storage directory (not Camera Roll), and save the file name in an sqlite db.
I have tried so many different variations of this, but when it comes to writing the filestream to save the app hangs. Testing on iPad 3. Does ANYONE have a suggestion? This has been driving me nuts for days. I have searched the web but I am stumped.**
public var temp:File; // File Object to save name in database
protected function selectPicture():void
{
myCam = new CameraUI();
myCam.addEventListener(MediaEvent.COMPLETE, onComplete);
myCam.launch(MediaType.IMAGE);
}
protected function onComplete(event:MediaEvent):void {
//imageProblem.source = event.data.file.url;
var cameraUI:CameraUI = event.target as CameraUI;
var mediaPromise:MediaPromise = event.data;
var mpLoader:Loader = new Loader();
mpLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onMediaPromiseLoaded);
mpLoader.loadFilePromise(mediaPromise);
}
private function onMediaPromiseLoaded(e:Event):void
{
var mpLoaderInfo:LoaderInfo = e.target as LoaderInfo;
mpLoaderInfo.removeEventListener(Event.COMPLETE, onMediaPromiseLoaded);
this.imageProblem.source = mpLoaderInfo.loader;
var stream:FileStream = new FileStream();
stream.addEventListener(Event.COMPLETE, showComplete);
stream.addEventListener(IOErrorEvent.IO_ERROR, showError);
try{
this.messages.text = "Starting";
stream.open( temp, FileMode.WRITE );
stream.writeBytes(mpLoaderInfo.bytes);
stream.close();
}catch(e:Error){
this.messages.text = e.message;
}
}
protected function showError(e:IOErrorEvent):void{
this.messages.text = e.toString();
}
protected function showComplete(e:Event):void{
this.messages.text = "Completed Writing";
this.imgName.text = temp.url;
imagefile = temp;
deleteFlag = 1;
}
Application hangs due to you are trying to use file operation in Sync mode.
You need to use Async Mode operation instead of sync mode file operation.
stream.openAsync( temp, FileMode.WRITE );
Try with this
var stream:FileStream = new FileStream();
stream.addEventListener(Event.COMPLETE, showComplete);
stream.addEventListener(IOErrorEvent.IO_ERROR, showError);
stream.openAsync( temp, FileMode.WRITE );
stream.writeBytes(mpLoaderInfo.bytes);
stream.close();
Note when using async operation you need not use try catch.For handling error listen IOErrorEvent will catch if any error occurs.
I finally got this to work, I added comments below in the code to explain why it wasn't working.
public var temp:File;
protected function selectPicture():void
{
myCam = new CameraUI();
myCam.addEventListener(MediaEvent.COMPLETE, onComplete);
myCam.launch(MediaType.IMAGE);
}
protected function onComplete(event:MediaEvent):void {
//imageProblem.source = event.data.file.url;
var cameraUI:CameraUI = event.target as CameraUI;
var mediaPromise:MediaPromise = event.data;
var mpLoader:Loader = new Loader();
mpLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onMediaPromiseLoaded);
mpLoader.loadFilePromise(mediaPromise);
}
private function onMediaPromiseLoaded(e:Event):void
{
var mpLoaderInfo:LoaderInfo = e.target as LoaderInfo;
mpLoaderInfo.removeEventListener(Event.COMPLETE, onMediaPromiseLoaded);
this.imageProblem.source = mpLoaderInfo.loader;
/// Here was the solution
var bitmapDataA:BitmapData = new BitmapData(mpLoaderInfo.width, mpLoaderInfo.height);
bitmapDataA.draw(mpLoaderInfo.content,null,null,null,null,true);
/// I had to cast the loaderInfo as BitmapData
var bitmapDataB:BitmapData = resizeimage(bitmapDataA, int(mpLoaderInfo.width / 4), int(mpLoaderInfo.height/ 4)); // function to shrink the image
var c:CameraRoll = new CameraRoll();
c.addBitmapData(bitmapDataB);
var now:Date = new Date();
var f:File = File.applicationStorageDirectory.resolvePath("IMG" + now.seconds + now.minutes + ".jpg");
var stream:FileStream = new FileStream()
stream.open(f, FileMode.WRITE);
// Then had to redraw and encode as a jpeg before writing the file
var bytes:ByteArray = new ByteArray();
bytes = bitmapDataB.encode(new Rectangle(0,0, int(mpLoaderInfo.width / 4) , int(mpLoaderInfo.height / 4)), new JPEGEncoderOptions(80), bytes);
stream.writeBytes(bytes,0,bytes.bytesAvailable);
stream.close();
this.imgName.text = f.url;
imagefile = f;
deleteFlag = 1;
}
ActionScript does not seem to support loading a png synchronously. I have tried loading it asynchronously, but then there is the problem of making your function wait for the load to finish. I cannot accomplish this. I have tried calling both setInterval and setTimout in a while loop, and breaking when the load is complete, but I get some very mysterious behavior. For the function parameter, I pass a function called doNothing that is just an empty function. When I run, setInterval or setTimeout gets over and over, very quickly. They do not wait the time provided before calling again. Also, doNothing never gets called.
Here's my code:
private function getData(extension:String):Bitmap
{
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onComplete);
loader.contentLoaderInfo.addEventListener(ErrorEvent.ERROR, onComplete);
loader.load(new URLRequest(baseDir + extension));
while (bitmap == null)
{
var test:Number = setInterval(doNothing, 1000);
}
var ret:Bitmap = bitmap;
bitmap = null;
return ret;
}
function onComplete(event:Event):void
{
bitmap = Bitmap(LoaderInfo(event.target).content);
}
function doNothing():void
{
trace("did nothing");
}
while loop is not good here since it will cause your client to freeze (and 15 seconds of freezing will throw an error)
Suggested Implementation:
private var loader:Loader;
private var onSuccess:Function;
// onSuccess = function (bitmap:Bitmap) : void
// onFail = function (e:ErrorEvent) : void
private function getData(extension:String, onSuccess:Function, onFail:Function):void
{
this.onSucess = onSuccess;
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onFail);
loader.contentLoaderInfo.addEventListener(ErrorEvent.ERROR, onFail);
loader.load(new URLRequest(baseDir + extension));
}
private function onComplete(event:Event):void
{
bitmap = Bitmap(LoaderInfo(event.target).content);
onSuccess.call(null, bitmap);
dispose();
}
private function dispose():void
{
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onComplete);
loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onFail);
loader.contentLoaderInfo.removeEventListener(ErrorEvent.ERROR, onFail);
this.loader = null;
this.onSuccess = null;
}
Does anyone have any experience with the Camera APIs in Flex 4.6 with iOS? I'm running into a lot of setup issues and the documentation is lacking. I'm trying to setup an image upload component where a user can either capture a new photo or choose an existing from their library.
For capturing, there seems to be a huge hang (like 10 seconds where the app just sits non-responsive) when the image is being saved as a JPEG, and I'm using the Alchemy swc.
private var cam:CameraUI;
protected function takePhotoHandler(event:MouseEvent):void
{
if(CameraUI.isSupported) {
cam = new CameraUI();
cam.addEventListener(MediaEvent.COMPLETE, mediaEventComplete);
cam.launch(MediaType.IMAGE);
}
}
protected function mediaEventComplete(e:MediaEvent):void
{
cam.removeEventListener(MediaEvent.COMPLETE, mediaEventComplete);
status.text = "Media captured..." ;
var imagePromise:MediaPromise = e.data;
var loader:Loader = new Loader();
if(imagePromise.isAsync) {
status.text = "Asynchronous media promise." ;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, asyncImageLoadHandler);
loader.addEventListener(IOErrorEvent.IO_ERROR, asyncImageErrorHandler);
loader.loadFilePromise(imagePromise);
} else {
status.text = "Synchronous media promise.";
loader.loadFilePromise(imagePromise);
img.source = loader.content;
saveImage(loader.contentLoaderInfo);
}
}
protected function asyncImageLoadHandler(e:Event):void
{
status.text = "Media loaded in memory.";
img.source = e.currentTarget.loader.content;
saveImage(e.currentTarget.loader.contentLoaderInfo);
}
protected function saveImage(loaderInfo:LoaderInfo):void
{
if(CameraRoll.supportsAddBitmapData){
var bitmapData:BitmapData = new BitmapData(loaderInfo.width, loaderInfo.height);
bitmapData.draw(loaderInfo.loader);
d_trace("bitmapDraw");
//var c:CameraRoll = new CameraRoll();
//c.addBitmapData(bitmapData);
d_trace("writing to disk");
var f:File = File.applicationStorageDirectory.resolvePath("temp");
var stream:FileStream = new FileStream()
stream.open(f, FileMode.WRITE);
d_trace("encoding start");
var baSource: ByteArray = bitmapData.clone().getPixels( new Rectangle( 0, 0, loaderInfo.width, loaderInfo.height) );
var bytes: ByteArray = as3_jpeg_wrapper.write_jpeg_file(baSource, loaderInfo.width, loaderInfo.height, 3, 2, 80);
d_trace("encoding end");
stream.writeBytes(bytes,0,bytes.bytesAvailable);
stream.close();
d_trace(f.url);
img.source = f.url;
d_trace("UPLOADING START");
f.addEventListener(Event.COMPLETE,uploadCompleteHandler);
f.addEventListener(Event.OPEN,openUploadHandler);
f.upload(urlRequest);
}
}
For choosing from the library, I can't get a file reference to actually start the upload. When the select is made, the mediaPromise.file value is null. mediaPromise.isAsync is true and I can attach a loader listener but that only returns the contentLoaderInfo, which has no reference to the actual File or a FileRefernce, so I can't call the upload method without creating a temp image, which seems expensive and crazy.
protected function chooseImage(): void {
if(CameraRoll.supportsBrowseForImage) {
var roll: CameraRoll = newCameraRoll();
roll.addEventListener( MediaEvent.SELECT, roll_selectHandler );
var options:CameraRollBrowseOptions = new CameraRollBrowseOptions();
roll.browseForImage(options);
}}
private function roll_selectHandler( event: MediaEvent ): void
{
var imagePromise:MediaPromise = event.data;
if(imagePromise.isAsync) {
// Here's where I get. Not sure how to get the reference to the file I just selected.
}}
Any help would be appreciated.
Thanks!
I think I found a solution for works for my case so I wanted to share it in case it can help someone out. shaunhusain's post definitely got me moving in the right direction. I was able to avoid using the Alchemy swc all together which saves a TON of time in the app. The key is this AS3 library I found that formats a URLRequest in a way that mimics a standard file upload POST operation. Here's the basic outline:
I have a small component called 'status' thats an overlay with an icon and status text for the user. When a user wants to add a photo, they get a ViewMenu with the choices to get the photo from their library or take a new photo. The meat of the code is below.
//IMAGE HANDLING
//Helpful Links:
//http://www.quietless.com/kitchen/dynamically-create-an-image-in-flash-and-save-it-to-the-desktop-or-server/
//http://stackoverflow.com/questions/597947/how-can-i-send-a-bytearray-from-flash-and-some-form-data-to-php
// GET WRAPPER CLASS Here: http://code.google.com/p/asfeedback/source/browse/trunk/com/marston/utils/URLRequestWrapper.as
//This part is basically all based on http://www.adobe.com/devnet/air/articles/uploading-images-media-promise.html
protected var cameraRoll:CameraRoll = new CameraRoll();
//User choose to pick a photo from their library
protected function chooseImage():void {
if( CameraRoll.supportsBrowseForImage )
{
cameraRoll.addEventListener( MediaEvent.SELECT, imageSelected );
cameraRoll.addEventListener( Event.CANCEL, browseCanceled );
cameraRoll.addEventListener( ErrorEvent.ERROR, mediaError );
cameraRoll.browseForImage();
} else {
trace( "Image browsing is not supported on this device.");
}
}
//User choose to take a new photo!
protected var cameraUI:CameraUI = new CameraUI();
protected function captureImage():void
{
if( CameraUI.isSupported )
{
trace( "Initializing..." );
cameraUI.addEventListener( MediaEvent.COMPLETE, imageSelected );
cameraUI.addEventListener( Event.CANCEL, browseCanceled );
cameraUI.addEventListener( ErrorEvent.ERROR, mediaError );
cameraUI.launch( MediaType.IMAGE );
} else {
trace( "CameraUI is not supported.");
}
}
private function browseCanceled (e:Event):void
{
trace ("Camera Operation Cancelled");
}
private function mediaError (e:ErrorEvent):void
{
trace ("mediaError");
}
private var dataSource:IDataInput;
private function imageSelected( event:MediaEvent ):void
{
trace( "Media selected..." );
var imagePromise:MediaPromise = event.data;
dataSource = imagePromise.open();
if( imagePromise.isAsync )
{
trace( "Asynchronous media promise." );
var eventSource:IEventDispatcher = dataSource as IEventDispatcher;
eventSource.addEventListener( Event.COMPLETE, onMediaLoaded );
} else {
trace( "Synchronous media promise." );
readMediaData();
}
}
private function onMediaLoaded( event:Event ):void
{
trace("Media load complete");
readMediaData();
}
private function readMediaData():void
{
var imageBytes:ByteArray = new ByteArray();
dataSource.readBytes( imageBytes );
upload(imageBytes);
}
//OK Here's where it gets sent. Once the IDataInput has read the bytes of the image, we can send it via our custom URLRequestWrapper
//which will format the request so the server interprets it was a normal file upload. Your params will get encoded as well
//I used Uploadify this time but I've used this Wrapper class in other projects with success
protected function upload( ba:ByteArray, fileName:String = null ):void
{
if( fileName == null ) //Make a name with correct file type
{
var now:Date = new Date();
fileName = "IMG" + now.fullYear + now.month +now.day +
now.hours + now.minutes + now.seconds + ".jpg";
}
var loader:URLLoader = new URLLoader();
loader.dataFormat= URLLoaderDataFormat.BINARY;
var params:Object = {};
params.name = fileName;
params.user_id = model.user.user_id;
var wrapper:URLRequestWrapper = new URLRequestWrapper(ba, fileName, null, params);
wrapper.url = "http://www.your-domain.com/uploadify.php";
loader.addEventListener( Event.COMPLETE, onUploadComplete );
loader.addEventListener(IOErrorEvent.IO_ERROR, onUploadError );
loader.load(wrapper.request);
}
private function onUploadComplete(e:Event):void
{
trace("UPLOAD COMPLETE");
var bytes:ByteArray = e.currentTarget.data as ByteArray;
//Most likely you'd want a server response. It will be returned as a ByteArray, so you can get back to the string:
trace("RESPONSE", bytes.toString());
}
private function onUploadError(e:IOErrorEvent):void
{
trace("IOERROR", e.text);
}