Can't display a very big image after loaded - actionscript-3

I have a big JPEG image file. It's dimension is 19000*14000 and the file size is about 41M. i'm using AIR 3.3 SDK, but after the load completes I can't see the image on stage. Does anyone know what the cause of this issue is?
Here is my code:
protected function button1_clickHandler(event:MouseEvent):void
{
file = new File();
file.addEventListener(Event.SELECT, imageFileHandler);
file.browseForOpen("image file", [new FileFilter("image file","*.jpg;*.jpeg")]);
}
protected function imageFileHandler(event:Event):void
{
fs = new FileStream();
fs.openAsync(file, FileMode.READ);
fs.addEventListener(Event.COMPLETE, bytesComplete);
}
protected function bytesComplete(event:Event):void
{
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoadHandler);
var bytes:ByteArray = new ByteArray();
fs.readBytes(bytes);
loader.loadBytes(bytes);
fs.close();
}
protected function imageLoadHandler(event:Event):void
{
image.source = (loader.content as Bitmap).bitmapData;
}

flash player and air has a limit for image file sizes to display. If i remember right, its 4096*4096. If you want to use a huge image, slice it to more, smaller images, load them separately, and place them one by one. its like you'd want google maps to load the whole earth. it just only loads the visible part. you should consider that as well.
you can also try resizing either the bitmapdata, either the sprite containing it to make the image visible.

I bet your stage is smaller than the actual image.
Create a bitmapData that is as big as your stage.
use copyPixels of BitmapData to copy the pixels from the big one to the little one (you can decal a x and y position of course).
Make sure you do bitmapData.lock() before the copyPixels is used and unlock() afterwards. These prevent useless updates that WILL cause slowing down, even crashes. copyPixels is a "fat" method :D
This way you don't have to split it in pieces. You can add this update for enterframe or on mousemove.

Related

Converting MovieClip to Bitmap with Dispose()

I am working on a mobile game using Flash CS6 with AIR. also design and coding on same platform (not using starling etc.).
I am converting movieClips (static, not animated) to bitmap dynamically and its working fine. But i realize with this process bitmapData caching on memory and with big shapes it takes a lot of memory. Then i decide to after added to stage clear to bitmapData by dispose(). But its removes from stage and anywhere its shown.
My code;
var target:MovieClip = new Ex_mc2();
target.x=100;
target.y=300;
addChild(target);
var bounds:Rectangle = target.getBounds(this);
var bmpData:BitmapData = new BitmapData(Math.floor(bounds.width), Math.floor(bounds.height), true, 0);
var bmpMatrix:Matrix = target.transform.matrix;
bmpMatrix.translate(-bounds.x, -bounds.y); // Draw bitmap
bmpData.draw(target, bmpMatrix);
var bmp:Bitmap = new Bitmap(bmpData);
bmp.x=100;
bmp.y=300;
addChild(bmp);
removeChild(target);
//bmpData.dispose(); I want to use this and i dont want my bmp disappear
Searching to solution for one week but i cant figure it out.
So my question is;
Can i converting movieClips to bitmap with freeing to memory? Like adding stage a static png file?
BitmapData -- is actually what's being shown on the screen. The format is almost identical to BMP, but the order of bytes is reversed. Bitmap is only a display container, serving to output image content to the screen and providing common DisplayObject APIs.
So, if you use BitmapData.dispose(), you are actually freeing the memory occupied by image and obviously after that there is nothing to be shown by Bitmap container.

Starling - load SWF image(vector) into a Image

I'm trying to convert an old project of mine to use Starling for some extra performance.
I've come to a problem when I'm loading my SWFs and trying to display them.
Here is the code I used before: (no Starling)
private function swfLoaded(e:LoaderEvent):void {
var spr:Sprite = new Sprite();
spr = e.currentTarget.content;
bitmapData.draw(spr ...);
}
The problem when I'm using Starling is that the currentTarget.content is a flash.display.displayObject.
cannot convert com.greensock.loading.display::ContentDisplay#90ffec1 to starling.display.Sprite
I want to find a way to "convert" the flash.display.displayObject into a starling Sprite.
I also want to be able to store the loaded swfs content into a array as a sprite.
Thanks in advance,
Tompa
You're overwriting spr with a different value immediately after you create it, for one thing.
After you do the bitmapData.draw() call:
var tex:Texture = Texture.fromBitmapData(bitmapData, false, false);
The new texture can then be used to create a Starling Image sprite.

addChild(): How can I know when a DisplayObject is actually displayed on the stage?

I've got a large (4096x4096) image loaded into memory, but when I try to use addChild, there is a long delay before it actually gets drawn to the screen. This is expected. However, is there an event I can listen for to know the moment that the DisplayObject (a .png image) is actually drawn to the screen?
I am trying to load the images onto the screen, then do something after they are actually drawn.
The delay is due to Flash Player decompressing the image in preparation for rendering.
The trick is to force Flash Player to decompress before you need it - then it will 'instantly' appear on the stage.
I can't take any credit for idea - but i'll take the bounty ;). Here's the article that enlightened me and explains it fully: http://jacksondunstan.com/articles/2080
If you are using a Loader class it's because the content isn't loaded yet.
Somewhere in your code you probably have something like this:
var loader : Loader = new Loader();
loader.load( new URLRequest( "theURL" ) );
stage.addChild( loader );
Now, this all happens in a few milliseconds. The content that you are loading isn't actually loaded yet though. The Loader is on the stage, but the content isn't placed in the loader until it is done loading.
Here's what you need to do.
var loader : Loader = new Loader();
loader.contentLoaderInfo.addEventListener( Event.COMPLETE, onImageLoaded, false, 0, true );
loader.load( new URLRequest( "theURL" ) );
stage.addChild( loader );
Then have this function in the same scope.
function onImageLoaded( evt : Event ) : void
{
loader.contentLoaderInfo.removeEventListener( Event.COMPLETE, onImageLoaded );
}
In that function the image and all its properties will be accessible. It may not be actually drawn to the screen yet, but that will happen on the next frame which is probably within a few milliseconds, but as far as the code is concerned, it's on stage.
Hope that helps!

Cannot mask Stage3D SWF in Loader

Working in FlashBuilder, I build a mobile AS3 application that uses a Loader to display a local SWF file. It masks the loader so it only shows a 640x480 window. This worked fine using an old SWF file (a Flixel game, non-Stage3D).
I then tried it with a Stage3D-enabled SWF file. This failed to run, because the application was not set to run in the 'direct' renderMode (it had been in auto up until this point). This allowed the application to run, but the SWF file now ignores the Loader's mask and displays across the entire stage.
Is it not possible to mask Stage3D SWFs when loaded in this way? The loading looks like so:
public function FlixelTest()
{
super();
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
myLoader.x = (stage.fullScreenWidth-640)/2;
myLoader.y = (stage.fullScreenHeight-480)/2;
var url:URLRequest = new URLRequest("stage3dswf.swf"); // in this case both SWFs are in the same folder
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadProdComplete);
myLoader.load(url); // load the SWF file
addChild(myLoader);
}
private function loadProdComplete(e:Event):void{
var gameMask : Shape = new Shape;
gameMask.graphics.beginFill(0xffcc00);
gameMask.graphics.drawRect(myLoader.x,myLoader.y,640,480);
gameMask.graphics.endFill();
myLoader.content.mask = gameMask;
}
As you can read in Adobe's documentation on Stage3D, the special Stage3D layers are located "behind" the regular stage used for 2D content.
Since any mask applied within the 2D stage exists in a different display list, there is no way to use 2D masks on Stage3D content. If at all possible, the only way to get similar results is to use 3D layers and alpha masks within the Stage3D context.

Screendump from within Actionscript 3.0 is it possible or?

We have Bitmap and Bitmapdata objects now. And when using the webcam, we can get raw-pixeldata output from it. But, can we get raw-pixeldata from the "stage" or "swf" object somehow?
I would like to use this to make "small thumbnails" of certain parts of Actionscript applications and these could be complex compositions of dynamic text, bitmap graphics and movieclips at the same time. So it would be nice to make a "quick snap" and just get the current combined pixels into one bitmap and then be able to "save that for later use".
Is that possible? is it too easy? am I just looking the wrong place in the Adobe Docs?
We have images, vectors etc at the same time on stage, so I need to grab the "stage" objects bitmapdata???
Create a BitmapData and call its draw() method with the corresponding DisplayObject
var bmpData:BitmapData = new BitmapData(sprite.width, sprite.height, true);
bmpData.draw(sprite);
If you want to make thumbnails smaller, create a Matrix and call its createBox method with required scaling parameters and pass it to the draw method.
var bmpData:BitmapData = new BitmapData(thumbW, thumbH, true);
var mat:Matrix = new Matrix();
mat.createBox(thumbW / sprite.width, thumbH / sprite.height);
bmpData.draw(sprite, mat);