Getting a bitmap of a spark window - actionscript-3

I have an AIR application that I'm working on in which I would like to basically get a bitmap of what's going on in a separate spark window. The use case is a scaled preview of the spark window that will likely be on a projector to the main display. I want to pump the bitmap into a spark image as a source. Googling this doesn't seem to reveal much or I just don't what terms to google. Can anybody point me in the right direction? Anybody have a better way to accomplish this?
Thanks!

If you would like to make a bitmap of some DisplayObject, be it the whole window (stage) or just a Sprite, you should use the BitmapData's draw() method.
The following code will take a "screen shoot" of the whole stage, make a bitmap image of it and add it scaled to the top left corner:
var bd:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
bd.draw(stage);
var bitmap:Bitmap = new Bitmap(bd);
bitmap.width = 300;
bitmap.scaleY = bitmap.scaleX;
addChild(bitmap);
It would benefit you to read more on Bitmap and BitmapData to utilize such features as:
Pixel snapping
Smoothing
Transparency
and others. For example smoothing is something that would make the image look better when scaled, but it counts as a filter and can be a performance hitter. That's why it would be better to apply smoothing on the bitmapdata when drawing (drawing scaled image is done with the matrix), not on a bitmap; but only when you don't plan to scale the image during runtime.
Hope that answers your question!

Related

As3 Actionscript drawing within the outlines

I am developing a coloring game using adobe air and as3. I have an image with black outline and the user can draw / color the image using a pen tool. I need help to figure out how can I restrict the user to draw within the outlines only. Masking the image with the line-graphics is something I have tried but it hangs the application. Any hint / suggestion towards the solution is appreciated.
following is the code on mouse_down event
_dot = new MovieClip();
_dot.graphics.lineStyle(lineSize, color);
_dot.graphics.moveTo(img.mouseX,img.mouseY);
img.addChild(_dot);
Let's say, the area you are drawing on is a DisplayObject with an instance name of Canvas. What you need is to check if the mouse is on Canvas or not.
In order to do so, you want to use the DisplayObject.hitTestPoint(...) method with the shapeFlag set to true (if it is false, it tests the point against the object's rectangle bounding box, which would produce the wrong results for any non-rectangular or rotated shapes).
So, you do as following:
var P:Point = new Point;
// First, convert coordinates to Stage coordinates,
// because the method requires so.
P.x = Canvas.mouseX;
P.y = Canvas.mouseY;
P = Canvas.localToGlobal(P);
// Now, test if the mouse is within the given canvas.
if (Canvas.hitTestPoint(P.x, P.y, true))
{
// The drawing should happen here.
}

As3 change object width/height, then set new size scale as 1

I have an object manipulation function that(right now) manipulates the scale of the objects inside of an array to give real-time size changes in relation with each other.
What I would like to know is if there's a way to change an object's width/height(to fit the screen size since it's a mobile app) and then reset the scale so that the new width/height has a scaleX/scaleY value of 1.
The width/height are properties that directly influence the scale of a DisplayObject. You cannot resize it without affecting the scale.
You can however:
Draw the image as bitmap
Redraw it if it's a primitive
Put it in a holder
A little about every solution:
Drawing a DisplayObject (or any IBitmapDrawable) is done through creating a BitmapData and using a draw() call. The up-side is that it will be a bitmap and thus save some rendering time. The downside is that if it's a large image it will take memory (can be critical for mobile) and it won't have interactivity/animation unless you make a script that would read the animation.
If you're drawing the element though the Graphics class's API, you might just make something like a resize() method that you would call on window resize/flip-orientation. Just utilise the clear() method of the Graphics object and redraw the whole thing.
Lastly, probably your best pick. Resize your object. Make a new Sprite (I choose Sprite because it's interactive and you probably want that) and add the resized object to that newly made sprite while the Sprite is just added to the display list like you added the resized object before. If it's hard to understand, here's some code:
myResizeableObject.width = newWidth;
myResizeableObject.scaleY = newScaleY;
var holderSprite:Sprite = new Sprite();
myResizeableObject.parent.addChild(holderSprite); // if you don't have a specific place to add the myResizeableObject, don't use myResizeableObject.parent - it's ugly
holderSprite.addChild(myResizeableObject);
Hope that helps you!

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.

as3 crop image loaded as MC

Hi this kills me :) I am using senocular for as3 move,rotate,scale,skew loaded image into MC and works great, but spent a lot of time, can't find nice solution for cropping such MC (with loaded image) with mouse. Do someone have solution (code) for this?
To display the cropped area, all you need to do is apply a mask, which is just another Display Object.
I haven't used Senocular's code for this, but if you make the mask the target of his move / scale code, then you can easily implement cropping. There's plenty on masking in the Adobe docs: http://livedocs.adobe.com/flex/3/html/help.html?content=05_Display_Programming_28.html
In practice, you have to hide the resize / move controls when cropping, and vice-versa, which is why tools like Flash itself, or Photoshop, have separate transform and crop modes.
From Senocular's docs:
// import for the Transform Tool classes used
import com.senocular.display.transform.*;
// create a box object to interact with
var box:Sprite = new Sprite();
addChild(box);
box.graphics.beginFill(0xAACCDD);
box.graphics.drawRect(-50, -50, 100, 100);
box.x = 100;
box.y = 100;
// create the Transform Tool
var tool:TransformTool = new TransformTool(new ControlSetStandard());
addChild(tool);
// select the box with the transform tool when clicked.
// deselect when clicking on the stage
box.addEventListener(MouseEvent.MOUSE_DOWN, tool.select);
stage.addEventListener(MouseEvent.MOUSE_DOWN, tool.deselect);
Just do this, but box needs to be the mask of your movie clip, so that when you resize it, you will crop the movie clip.

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