add `movieclip` from external swf's library - actionscript-3

I loaded External swf file to stage :
var mcLoader = new Loader();
this.addChild(mcLoader);
mcLoader.load(new URLRequest("E:\\MySWF.swf"));
var mcLoader = new Loader();
this.addChild(mcLoader);
now I want to add a movieclip from external swf's library with "Part3" as linkage name, I did like below :
var cls:Class = mcLoader.contentLoaderInfo.applicationDomain.getDefinition("Part3") as Class;
var MCCurrentPart = new cls;
but it didn't work, After that I tried like this :
var MCCurrentPart = new mcLoader.content.Part2;
but now it gives error : Instantiation attempted on a non-constructor.

Your use of getDefinition() is fine, just you have to wait until the Event.COMPLETE event in the contentLoaderInfo of the Loader is fired.
So you can do like this :
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, on_content_load);
loader.load(new URLRequest('swf.swf'));
function on_content_load(e:Event): void
{
var MyClass:Class = loader.contentLoaderInfo.applicationDomain.getDefinition('MyClass') as Class;
var obj = new MyClass;
addChild(obj);
}
You can take a look in some examples from Adobe here.
Hope that can help.

Related

loadermax to get qualified class name of the swf

The typical as3 code would be like this
private function load():void {
var loaderContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
if(Security.sandboxType == Security.REMOTE) {
loaderContext.securityDomain = SecurityDomain.currentDomain;
}
loader.contentLoaderInfo.addEventListener(Event.INIT, handleInit);
loader.load(new URLRequest("capture.swf"), loaderContext);
}
private function handleInit(event:Event){
var className:String = getQualifiedClassName(loader.content);
var classRef:Class = loader.contentLoaderInfo.applicationDomain.getDefinition(className) as Class;
var captureModule = new classRef();
addChild(captureModule as DisplayObject);
}
now while using greensock's loadermax, how can I access the qualified class name, it's reference, create an object myself and add to display.
loaderMax.append(new SWFLoader("capture.swf", {name:"capture"}));
loaderMax.append(new SWFLoader("filter.swf", {name:"filter"}));
loaderMax.load();
the loadComplete function
function completeHandler(event:LoaderEvent): void {
trace(event.target + " is complete");
var capture = loaderMax.getContent("capture");
trace(getQualifiedClassName(capture)); //want to reach the custom class of the loaded sf
}
turns out that the loaded swf has a property loaderInfo.loader that you can access to use the loader.
var loader = loaderMax.getContent("capture").rawContent.loaderInfo.loader;
this.data["capture"] = loader.contentLoaderInfo.applicationDomain.getDefinition(getQualifiedClassName(loaderMax.getContent("capture").rawContent)) as Class;

How to create a sprite from an image loaded in Loader()?

I'm loading a background image via the Loader() class and wanted to know if there's a way to create a sprite from that loaded image?
I'm wanting to put a function in an external class file to put the image in the loader and then call the class to create a sprite from the loaded image. I'm not even sure this is possible.
Note: I'm using flashdevelop and no timeline.
You can just use the loader object as a display object or you can access the Bitmap object in the loader and add that to a sprite.
var loader:Loader = new Loader();
loader.load(new URLRequest(filename));
addChild(loader);
loader.x = 100;
loader.y = 200;
//so on
To get access to the bitmap and bitmapdata loaded just add an event listener and access them.
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(new URLRequest(filename));
private function onLoadComplete(e:Event):void
{
var loaderInfo:LoaderInfo = e.target as LoaderInfo;
var loadedBitmap:Bitmap = loaderInfo.content as Bitmap;
var sprite:Sprite = new Sprite();
sprite.addChild(loadedBitmap);
addChild(sprite);
sprite.x = 100;
sprite.y = 200;
//so on
}

Modify dynamic created objects that are saved in an array

i have multiple images that are created dynamically, and i want in some cases to change the image. i can save them in an array, but how can i change the image (load another image) by getting it from the array.
let's say that i have an array:
var ImagesArray:Array = [];
and i push to it loader objects, and want to change (load new) image of ImagesArray[0] or ImagesArray[1]... like:
var loaderNew:Loader = new Loader();
loaderNew = ImagesArray[i];
loaderNew.load(new URLRequest("../lib/NewImg.png"));
Thanks,
You dont need to create new loader if you only want to change its image, here's an example of function to update image url:
private function changeImageByIndex(i:int, url:String):void
{
var loader:Loader = ImagesArray[i] as Loader;
if (!loader)
{
loader = new Loader();
addChild(loader);
ImagesArray[i] = loader;
}
loader.load(new URLRequest(url));
}
If you have bitmap, use loadBytes() method instead load(), here's example:
var bitmap:Bitmap = new Bitmap(new BitmapData(100, 100, true, 0xff0000));
var encoder:JPEGEncoder = new JPEGEncoder();
loader.loadBytes(encoder.encode(bitmap.bitmapData));

Actionscript 3: Converting bytearray to PNG and display on the scene

I'm getting getting a PNG image stored in SQL through a WCF get call. The image is encoded as a base64 string and delivered to my AS3 code. I need to extract the image from the data and show it on the scene.
Among other things, I have also tried this...
var imgArray:ByteArray = Base64.decodeToByteArray(responseXML.ImageObject);
var myRect:Rectangle = new Rectangle(100,100,200,200);
var bmd:BitmapData = new BitmapData(200,200,true,0xAAAAAAAA);
bmd.setPixels(myRect, imgArray);
var image:Bitmap = new Bitmap(bmd,"auto",true);
this.addChild(image);
but to no avail.
HELP!
why don't you use a loader and loadbytes? It's native.
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleLoad)
loader.loadbytes(byteArray);
private function handleLoad(e:Event):void {
var loader:Loader = e.currentTarget as Loader;
// removelistener,etc
trace(loader.content as Bitmap);
}
The problem with your code is that PNG is compressed, bitmap is uncompressed.
I used DanielH's input and got the image to load on my stage. Here is what I did in the event handler function...
function ImageLoaded(e:Event):void
{
var bmd:BitmapData = new BitmapData(imageLoader.ImageLoader.width,imageLoader.ImageLoader.height,true, 0xFFFFFF);
bmd.draw(imageLoader.ImageLoader);
var image:Bitmap = new Bitmap(bmd,"auto",true);
image.width=40;
image.height=40;
if(!CheckAndStoreImageIDKey(imageLoader.ImageID))
{
Images[imageLoader.ImageID] = image;
}
}
Try PNGDecoder (http://www.ionsden.com/content/pngdecoder)
import ion.utils.png.PNGDecoder;
var bmd:BitmapData = PNGDecoder.decodeImage(imgArray);

execute remote SWF in AIR Security Sandbox

I try to download an external SWF and run it within the AIR security sandbox.
this is the code of the AIR application:
public class Downloader extends Sprite
{
private static const REMOTE_FILE:URLRequest = new URLRequest("http://myserver.com/downloadable.swf");
private var _main:NativeWindow;
public function Downloader()
{
var loader:URLLoader = new URLLoader(REMOTE_FILE);
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, downloadComplete);
}
private function downloadComplete(e:Event):void{
var ba:ByteArray = e.target.data;
var stream:FileStream = new FileStream();
var file:File = File.applicationStorageDirectory.resolvePath("downloadable.swf");
stream.open(file, FileMode.WRITE);
stream.writeBytes(ba);
stream.close();
loadAndRunSwf();
}
private function loadAndRunSwf(){
this._main = new NativeWindow();
this._main.width = 1024;
this._main.height = 768;
////obsolete?
//var context:LoaderContext = new LoaderContext();
//context.allowLoadBytesCodeExecution = true;
//context.applicationDomain = ApplicationDomain.currentDomain;
var file:File = File.applicationStorageDirectory.resolvePath("downloadable.swf");
var loader:Loader = new Loader();
loader.load(new URLRequest(file.url)/*,context*/);
this._main.stage.addChild(loader);
this._main.activate();
}
}
Code of the downloadable.swf:
public class Downloadable extends Sprite
{
private var _btn:Button = new Button();
private var _baseFolder:File = new File("app-storage:/");
public function downloadable_test()
{
this.addChild(_btn);
_btn.label = "access Harddisk";
...
}
}
so now, If I run Downloader, it will download the swf and try to run it, but i'll get an exception in Downloadable on the line
private var _baseFolder:File = new File("app-storage:/");
the error:
SecurityError: file
at runtime::SecurityManager$/checkPrivilegeForCaller()
So - what Do I need to do to prevent such security errors? I want my remote SWF to be treated as native code running in the same security sandbox as the AIR code.
I'm not sure about Android, but for the regular web player you would need to specify SecurityDomain.currentDomain for the securityDomain of the Loader's context for the loaded code to be considered equal to the loader in terms of permissions. Also note that for reasons impossible to explain, if you use SecurityDomain when loading from the file system on PC Flash Player will complain.
However complicated, the Flash Player security is often a security by obscurity... So, if it doesn't work the way you coded it, try Loader.loadBytes() "workaround".
function loadAndRunSwf()
{
var context:LoaderContext=new LoaderContext(false);
context.allowCodeImport=true;
var ba:ByteArray=new ByteArray();
var file:File = File.applicationStorageDirectory.resolvePath("downloadable.swf");
var fileStream:FileStream=new FileStream();
var loader:Loader = new Loader();
fileStream.open(file,"read");
fileStream.readBytes(ba);
ba.position=0;
loader.loadBytes(ba,context);
this._main = new NativeWindow();
this._main.width = 1024;
this._main.height = 768;
this._main.stage.addChild(loader);
this._main.activate();
}