Converting MovieClip to Bitmap with Dispose() - actionscript-3

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.

Related

Can't display a very big image after loaded

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.

Starling AS3 -- How To Use Bitmap Objects in SWC

I'm trying to see how Starling could benefit the applications I build using as3. My knowledge thus far of Starling is that it only uses bitmap objects not symbol objects. How do I take a BitmapData class and create an starling Image out of it.
This bitmap was a symbol in flash that was converted into bitmap. It then had its properties modified to export for as3
Say there is a Ship BitmapData class in a swc.
According to Starlings documentation of how it handles other bitmap like a png, I would think I should be able to do this.
var myShip:Image = Image.fromBitmap(new Ship());
This of course doesn't work.
fromBitmap() expects to receive a bitmap object but here you are passing in a BitmapData Class. And Image class requires a texture.
Also your syntax is slightly incorrect.
NB. There is Texture.fromBitmap and Texture.fromBitmapData.
Although I haven't tried accessing assets from a swc you could try:
var myShip:Image = new Image(Texture.fromBitmapData(new Ship());
Perhaps try to get the Image appearing first before attempting to access the swc bitmapData
var bd:BitmapData = new BitmapData(100, 100, false, 0xFF0000);
var myShip:Image = new Image(Texture.fromBitmapData(bd);
addChild(myShip); //should display a red square

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.

AS3 Is it possible to duplicate a Shape object?

I'm trying to make a shape available for duplicating. Here's an explanation of what I've done, what I'm trying to do, and where I'm stuck:
Drew a shape manually in the Flash IDE (paintbrush).
Created a new movieclip containing the shape; exports as a class.
Instantiate the class (var mc:MovieClip = new shapeMovieClip()).
Add a reference to the shape in mc that I want (var myShape:Shape = mc.getChildAt(0) as Shape;
This works perfect and I now have my shape, but how can I duplicate it without instantiating the parent MovieClip class - is it possible?
I've tried creating a new shape and using the copyFrom() graphics method with no avail, I believe this method just copies draw calls when they're made on the referenced graphics and instead I just have a reference of a shape that's already been drawn.
Right now I'm extending the movieclip as a sprite instead, instantiating, pulling the shape from the parent and saving its reference, and then nulling the sprite. Does anyone know of a better, more lightweight, strategy for duplicating Shapes in this manner?
Basically depends on whether you need to scale your shapes. If you don't, and you can work it out with a fixed sized bitmap representation of the shape, then you will get much better performance drawing your shape to a BitmapData (it's called rasterisation) and instanciating Bitmap objects (as other commenters have pointed out). The code would go something like this:
var base:Sprite = new shapeMovieClip();
var bmd:BitmapData = new BitmapData(base.width, base.height, true, 0);
bmd.draw(base);
var clip1:Bitmap = new Bitmap(bmd);
var clip2:Bitmap = new Bitmap(bmd);
If you do need to scale the clips, you will get pixelation using bitmaps. When scaling down Bitmap.smoothing can help to some extent (also when rotating), but if you need to scale up, you will probably have to use some kind of mip-mapping. This is basically creating a few bitmaps of the shape at different scale levels, and then swap them depending on the current scale. Coding this has some complexity (using a helper parent to adjust the scale can help) but it will definitely perform better than using many shape symbols (with or without a sprite parent).
This is very old, but it still comes up high in Google, so I just wanted to share a true shape duplicating method:
var shapeonstage:Shape = shapeMadeInIDE;
var g:Vector.<IGraphicsData> = shapeonstage.graphics.readGraphicsData();
var shapecopy:Shape = new Shape();
shapecopy.graphics.drawGraphicsData(g)
And boom. It works. Had to share this because it would have helped me a looooong time ago and in so many ways.
UPDATE:
There is some clarification I'd like to add why you would want to use this method, for duplicating AND for storing references to Shapes that are within an swf.
If you target a Shape object on the stage or in a movie clip, the Flash Rendering engine does something strange. It will RECYCLE Shape objects to render new graphics thus making your Shape reference point to a COMPLETELY different rendering.
For example:
Create an fla with a movieclip.
Inside the movie clip make 10 frames.
On each frame, draw a different shape
In your code, get a reference to the shape (The Shape on Frame 1)
Draw and verify your shape (draw to a bitmap then put the bmp on stage)
Now let the flash engine play for 5 frames
Draw and verify your shape again
The second time you draw your shape without EVER reassigning your shape reference, will SOMETIMES yield a completely different shape.
Just know, this little quirk can leave you pulling your hair out if you don't know what you're looking for :)

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);