AS3 - Convert String to Bitmap - actionscript-3

I'm trying to store my images on a server to lighten the load of my SWF file. I've spent all day trying to get the data from the server, but all I get is a seemingly random string (which I understand is the string value of my image). I've tried reading up on this, but I haven't found anything that actually works, I get a lot of references to Base 64 encoding/decoding and I've tried a couple of libraries but they do nothing. Here's what I have (I've simplified it a bit to upload it):
public function loadImage() : void {
var url:String='example.com/some_image';
var load:URLLoader=new URLLoader(new URLRequest(url));
load.addEventListener(Event.COMPLETE, onLoadComplete);
}
public function onLoadComplete(event : Event) : void {
var imgString:String=event.target.data;
}
But how do I convert imgString to a Bitmap or Sprite so I can addChild() it? I've tried imgString as Bitmap which returns null. Maybe it has something to do with the BitmapData class? This post seems similar but is unanswered.

If you have a server that runs PHP, you can generate the image first, e.g.
// PHP script 'http://yoursite.com/image.php
header("Content-type: image/jpeg");
echo $myImageDataFromDB; // Get the image data from MySQL.
And then in ActionScript, use the standard process to load that as an image:
var request:URLRequest = new URLRequest("http://yoursite.com/image.php");
var loader:Loader = new Loader();
loader.load(request);
addChild(loader);

Related

AS3-embedded SWF comes up as null

So I have a SWF embedded in my AS3 project, but when I try to do anything with it, it says it's null.
The code looks like this:
[Embed(source = "../lib/Introduction.swf", mimeType = "application/octet-stream")]
public var introClass:Class;
(after a bunch of irrelevant stuff...)
var intro:MovieClip = new introClass() as MovieClip;
intro.play();
(The error message it gives me is a standard #1009 error.)
I've tried a bunch of stuff including using Loaders, not using MovieClip, etc, but at best, only the audio (not the video) of the SWF loads up, and at worst, the entire application crashes when the SWF tries to load. How do I get the SWF to be recognized?
(I'm using FlashDevelop if that helps.)
You can do this:
[Embed(source="asset.swf", symbol="symbol")]
private var symbolClass:Class;
var symbol:MovieClip = new symbolClass();
If you want to embed a symbol from an art SWF.
Instead if you want to import animations this is the solution:
[Embed(source="/loading.swf", mimeType="application/octet-stream")]
public var LoadingAnimation : Class;
// allows us to import SWFs to use as animations
var context : LoaderContext = new LoaderContext (false,
ApplicationDomain.currentDomain);
context.allowCodeImport = true;
var loader : Loader = new Loader ();
loader.loadBytes (new LoadingAnimation (), context);

AS3 Retrieving a file from FZip

I am currently coding a game and I am storing all external files in a zip file to save space.
I am trying to use Fzip to load an image out of the Zip file and display it on stage but I am having no luck.
FZip Site - http://codeazur.com.br/lab/fzip/
Example 1 Site - http://www.tuicool.com/articles/7VfQr2
I have got the zip file to load and return me the number of files inside it but I cannot figure out how to retrieve an image called "test.png".
import deng.fzip.FZip;
import deng.fzip.FZipFile;
import deng.fzip.FZipLibrary;
import flash.display.*;
var zip:FZip = new FZip();
var loaderzippy:Loader = new Loader();
function unzipObb():void {
zip.load(new URLRequest("file://"+File.applicationStorageDirectory.nativePath+"/cake2.zip"​));
zip.addEventListener(Event.OPEN, onOpen);
zip.addEventListener(Event.COMPLETE, dosomething); }
function dosomething(evt:Event):void {
trace("dosomething");
var img_file:FZipFile = zip.getFileByName("test.png");
var loaderzip:Loader = new Loader();
loaderzip.loadBytes(img_file.content);
var image:Bitmap = Bitmap(loaderzip.content);
addChild(image); }
I just get returned #2007: Parameter child must be non-null.
Any help would be great. Thanks.
When you load the PNG bytes using loaderzip.loadBytes(), you need an event listener to check when it's done loading. The documentation itself states:
The loadBytes() method is asynchronous. You must wait for the "init" event before accessing the properties of a loaded object.
Because you're trying to access the code directly after you called loadBytes(), at which point it hasn't actually loaded anything, you're getting a null bitmap.
Although you can access the data once the "init" event has been dispatched, it's best to wait for the "complete" event, since you want your image to be done loading (rather than halfway done).
I've tweaked your code to something that should work:
function dosomething(evt:Event):void {
trace("dosomething");
var img_file:FZipFile = zip.getFileByName("test.png");
var loaderzip:Loader = new Loader();
loaderzip.contentLoaderInfo.addEventListener(Event.COMPLETE, getImage);
loaderzip.loadBytes(img_file.content);
}
function getImage(e:Event):void {
var loaderInfo:LoaderInfo = e.currentTarget as LoaderInfo;
var image:Bitmap = Bitmap(loaderInfo.content);
addChild(image);
}
(I haven't tested this myself but it's just to give you the general idea anyway.)
Note that you should add the event listener to loaderzip.contentLoaderInfo, not just loaderzip. That's what actually dispatches the event and it also contains the loaded content.

URLRequest multiple SWF links not working properly

I'm trying to load 3 different tickers in 3 different containers.
When I delete this line:
loader2.load(new URLRequest("http://tickers.playtech.com/jackpots/new_jackpot.swf?casino=cityclub&info=1&game=bl&font_face=Arial&bold=true&font_color=FFFFFF&bg_color=240000&font_size=24&currency=eur"));
loader3.load(new URLRequest("http://tickers.playtech.com/jackpots/new_jackpot.swf?casino=cityclub&info=1&game=bl&font_face=Arial&bold=true&font_color=FFFFFF&bg_color=240000&font_size=24&currency=eur"));
and load them separately they works fine:
but when i load them together, just as the written in this document in adobe, all three tickers showing the same number:
package {
import flash.display.MovieClip;
import flash.net.URLRequest;
import flash.display.Loader;
public class importExternalSWF extends MovieClip {
private var loader:Loader = new Loader();
private var loader2:Loader = new Loader();
private var loader3:Loader = new Loader();
public function importExternalSWF() {
loader.load(new URLRequest("http://tickers.playtech.com/jackpots/new_jackpot.swf?casino=cityclub&info=1&game=mrj-4&font_face=Arial&bold=true&font_color=FFFFFF&bg_color=240000&font_size=24&currency=eur"));
loader2.load(new URLRequest("http://tickers.playtech.com/jackpots/new_jackpot.swf?casino=cityclub&info=1&game=bl&font_face=Arial&bold=true&font_color=FFFFFF&bg_color=240000&font_size=24&currency=eur"));
loader3.load(new URLRequest("http://tickers.playtech.com/jackpots/new_jackpot.swf?casino=cityclub&info=1&game=grel&font_face=Arial&bold=true&font_color=FFFFFF&bg_color=240000&font_size=24&currency=eur"));
ticker1.addChild(loader);
ticker1.width=50;
ticker1.height=20;
ticker2.addChild(loader2);
ticker2.width=50;
ticker2.height=20;
ticker3.addChild(loader3);
ticker3.width=50;
ticker3.height=20;
}
}
}
I cant find solution anywhere
Thanks
edit
I rewrite my code to this, and its still the same result
public class importExternalSWF extends MovieClip {
public function importExternalSWF() {
var url = "http://tickers.playtech.com/jackpots/new_jackpot.swf";
var urlParams:Array = ["grel", "bl", "game=mrj-4"];
var tickers:Array = [ticker1, ticker2, ticker3];
var tickerHeight:Number = 50;
var tickerWidth:Number = 50;
loadUrls();
function loadUrls():void {
for(var i:uint = 0; i<urlParams.length; i++)
{
var urlLoader = new Loader();
var flashvars:URLVariables = new URLVariables();
flashvars["casino"] = "cityclub";
flashvars["info"] = "1";
flashvars["game"] = urlParams[i];
flashvars["currency"] = "eur";
flashvars["font_face"] = "arial";
flashvars["bold"] = "true";
flashvars["font_size"] = "10";
flashvars["bg_color"] = "0x000000";
flashvars["font_color"] = "ffffff";
var request:URLRequest = new URLRequest(url);
request.data = flashvars;
urlLoader.load(request);
tickers[i].width=tickerWidth;
tickers[i].height=tickerHeight;
tickers[i].addChild(urlLoader);
}
}
}
I suspect that the external SWF file sets some variables on the root level. Therefore each load will override the previous values and you'll end up with the same score in all "tickers".
Most likely this interference can be resolved by loading each SWF into its own ApplicationDomain. By default, SWFs are being loaded into the same ApplicationDomain and share their code.
So instead of doing this:
urlLoader.load(request);
You should do soemthing like this:
// create a new LoaderContext with a spearate ApplicationDomain
var context:LoaderContext = new LoaderContext(false, new ApplicationDomain());
// load the request and use the context with the separate ApplicationDomain
urlLoader.load(request, context);
I have bad news, i tried everything, but I can't load correctly the swf files. So, I have started to investigate this, and i found that, first, your SWF has AVM1Movie format (new_jackpot.swf), so, I conclude that this SWF was created with version 1 or 2 of ActionScript. If you see the reference of AVM1Movie Class (here the link), says the following:
There are several restrictions on an AVM1 SWF file loaded by an AVM2 SWF file:
The AVM1 SWF file that is loaded by an AVM2 SWF file cannot load another SWF file into this. That is, it cannot load another SWF file over itself. However, child Sprite objects, MovieClip objects, or other AVM1 SWF files loaded by this SWF file can load into this.
Then, i tried too, with a library that implements Threads in Flex, and found this (here this link async-threading):
The Actionscript Virtual Machine (AVM) in the Flash Player is severely limited by only having one thread...
I have created several projects using Loaders, SWFLoaders, ByteArrays, etc, all this in actionscript 3 in Flex SDK 3.2.
Maybe if you create this project in a previous version could work, or try to use same library that implements threads.
Anyway if I find something more, will edit this answer with another solution that's right.
Try adding a 1 after «laoder» at these places:
private var loader:Loader = new Loader();
loader.load(new URLRequest("http://tickers.playtech.com/jackpots/new_jackpot.swf?casino=cityclub&info=1&game=mrj-4&font_face=Arial&bold=true&font_color=FFFFFF&bg_color=240000&font_size=24&currency=eur"));
There was no solution to this issue due to lack of compatibility from third part company that provides the tickers.

AS3/FLEX - how to convert Sprite graphics into bytes

I wrote application that lets people paint together via internet (using Adobe cirrus). Everything works great but when for example I run my application and paint something before my friend connects, he dont see that what I have painted. So I'm looking for the method, that would let me convert my canvas into something(object) that it is possible to send by internet (I cant send whole Sprite, it's not possible to copy its graphics on the friend's application, it's null).
So let's get this clear. The main question is: How to convert graphic's of Sprite into object, that would let me convert it back to Sprite and copy its canvas.
ANSWER:
I used DisplayConverter library from "www.Flextras.com" post with his mod to convert Sprite to BitmapData and then to ByteArray and it works. I couldn't receive BitmapData on the friend's app, but It worked with ByteArray.
Sprite -> BitmapData -> ByteArray;
ByteArray -> BitmapData -> Sprite;
//TO SEND
var bitmapdata:BitmapData = DisplayConverter.spriteToBitmapData(palette);
var bytearr:ByteArray = bitmapdata.getPixels(bitmapdata.rect);
//TO RECEIVE
var bmd:BitmapData = new BitmapData(530,430);
bmd.setPixels(bmd.rect, bytearr);
mysprite.graphics.beginBitmapFill(bmd);
mysprite.graphics.drawRect(0,0,530,430);
mysprite.graphics.endFill();
Hope this will help someone
I think you want to convert your Canvas into a BitMap or BitMapData (and back). A Flex Canvas extends Sprite, so you can use a library like this one. To copy the relevant code, this will convert a Sprite to a BitMap:
public static function spriteToBitmap(sprite:Sprite, smoothing:Boolean = false):Bitmap
{
var bitmapData:BitmapData = new BitmapData(sprite.width, sprite.height, true, 0x00FFFFFF);
bitmapData.draw(sprite);
return new Bitmap(bitmapData, "auto", smoothing);
} // END FUNCTION spriteToBitmap
This will convert a Bit Map to a Sprite:
public static function bitmapToSprite(bitmap:Bitmap, smoothing:Boolean = false):Sprite
{
var sprite:Sprite = new Sprite();
sprite.addChild( new Bitmap(bitmap.bitmapData.clone(), "auto", smoothing) );
return sprite;
} // END FUNCTION bitmapToSprite
In my own development, I have a mod to this library, which allows me to get the BitMapData instead of an actual BitMap. So, this will turn a Sprite into BitMapData:
public static function spriteToBitmapData(sprite:Sprite):BitmapData
{
var bitmapData:BitmapData = new BitmapData(sprite.width, sprite.height, true, 0x00FFFFFF);
bitmapData.draw(sprite);
return bitmapData;
} // END FUNCTION spriteToBitmapData
This will take BitMapData and turn it back into a Sprite:
public static function bitmapDataToSprite(bitmapData:BitmapData, smoothing:Boolean = false):Sprite
{
var sprite:Sprite = new Sprite();
sprite.addChild( new Bitmap(bitmapData.clone(), "auto", smoothing) );
return sprite;
} // END FUNCTION bitmapToSprite
You do want to keep in mind that when converting the BitMap or BitMapData back into a Sprite you will probably not be able to cast it as a Canvas. For information on sending BitMapData to a server; look at this question.
A better approach is, instead of going directly to pixels, have the user gestures create data, then reflect that data as a drawing on your canvas. Transmit the same data to the other user and he/she will get the same drawing.

Embed bitmap in ActionScript3

How can I embed a bitmap in Actionscript 3 and get the BitmapData?
public class MyGame extends Sprite {
[EMBED(source="Assets/helicopter1.png")] private static var BMClass:Class;
public function MyGame() {
var BM:Bitmap = new BMClass();
var BMData:BitmapData = new BitmapData(BM.width, BM.height);
BMData.draw(BM)
}
}
I've tried everything. If I ever try to instantiate the embedded class (new BMClass();) I get this error:
TypeError: Error #1007: Instantiation attempted on a non-constructor..
If I use
[EMBED(source="Assets/helicopter1.png")] private static var BMClass:BitmapData;
or something similar the BitmapData is null.
Edit:
So I figured out that the embedded data is null, but I can't figure out why. What did I do wrong in the embedding?
Looks like you are embedding correctly if you don't get an error transcoding. You should be able to get the bitmapData directly from the bitmap:
[Embed(source="picture.jpg")]
private var Picture:Class;
// create a bitmap of the embedded
var pic:Bitmap = new Picture();
// add to display list
addChild(pic);
// if you need to get the bitmapData for something else
var bitmapData:BitmapData = pic.bitmapData;
You don't need to instantiate as BitmapData and draw - you can simply:
[Embed(source="Assets/helicopter1.png")]
private var AssetClass:Class;
var bitmap:Bitmap = new AssetClass();
In some editors (at least my version of Intellij) the Embed tag is case sensitive. I got the exact same error you have when using [EMBED] but it worked great when I switched to [Embed]