How do I rasterize a graphic that contains path data? - actionscript-3

I am trying to rasterize some SVG data to a PNG and it is not working. Could someone please tell me what I am doing wrong?
This code does not seem to have any data in the BitmapData object.
var color:uint = Math.floor( (Math.random() * 0xFFFF00) + 0x0000FF);
var graphic:Graphic = new Graphic();
graphic.graphics.beginFill(color);
var pathData:String = "M 0 0 L 0 40 L 40 40 L 40 40 Z";
var path:Path = new Path();
path.data = pathData;
path.x =0;
path.y=0;
path.width = 40;
path.height = 40;
path.stroke=new SolidColorStroke(100);
path.fill=new SolidColor(100);
path.winding = GraphicsPathWinding.EVEN_ODD;
graphic.addElement(path);
graphic.width = 40;
graphic.height = 40;
graphic.validateNow();
var FillColor = 0x00000000;
var bitMapData:BitmapData = new BitmapData(graphic.width,graphic.height, true, FillColor);
bitMapData.draw(graphic);
But this code does:
var graphic:Graphic = new Graphic();
graphic.graphics.beginFill(color);
var width:Number = Math.floor(Math.random() * (MAXWIDTH-MINWIDTH)) + MINWIDTH;
var height:Number = Math.floor(Math.random() * (MAXHEIGHT-MINHIEGHT)) + MINHIEGHT;
var radius:Number = Math.floor( (Math.random()*(MAXRADIUS-MINRADIUS)))+MINRADIUS;
width = height = radius*2;
graphic.graphics.drawCircle(radius, radius,radius );
graphic.graphics.endFill();
var FillColor = 0x00000000;
var bitMapData:BitmapData = new BitmapData(graphic.width,graphic.height, true, FillColor);
bitMapData.draw(graphic);
if I do:
var temp:Graphic = new Graphic();
temp.graphics.beginFill(0x000000);
temp.graphics.drawRect(0,0,width/2, height/2);
temp.graphics.endFill();
sprite.graphics.drawRect(0,0,width, height);
sprite.addElement(temp);
both rectangles draw on canvas, but
BitMapData.draw(sprite);
only shows the toplevel sprite.

So I figured it out. Paths use BeforeDraw(), Draw(), and EndDraw(), which performs the fill and stroke operations. The problem is that these functions dont get called until the path gets rendered on the canvas. So, I extended my path class and over-rode the EndDraw() function. In this function I dispatched an event. Then, when I catch the event I can get the DisplayObject from the path (which is now filled in) and pass that object into BitmapData().

Related

How to place multiple bitmaps in a scrollable rectangle? AS3

This code builds a palette of tiles for use in a map maker program. It takes in an array set by its parent and uses the bitmaps(from the objects) in that array to display a grid of tiles. Right now it only does a 5x5 grid, but what if there are more than 25 tiles in my tileSet? I want to display only the 5x5 tile grid, but be able to scroll through the images. I imagine that I need to make another rectangle to use as its mask and use a ScrollBar to make it scrollRect, but I can't get this working. Please Help.
public function Palette(X:uint, Y:uint, tileSet:Array)
{
addChild(handleGraphics);
var palette:Rectangle = new Rectangle(X, Y, 5*32, tileSet.length*32); //Default size is 5x5 tiles.
handleGraphics.DrawGrid(32,palette.x,palette.y,5,5);
var counter:int = 0;
for(var i:int = 0; i < 5; i++)
{
paletteArray[i] = [];
for(var u:int = 0; u < 5; u++)
{
if(counter >= tileSet.length)
{
counter = 0; //Which frame to show?
}
var b:Bitmap = new Bitmap(tileSet[counter].Graphic);
b.x = (palette.x) + 32 * u; //Align with palette Rectangle.
b.y = (palette.y) + 32 * i; ///////////////////////////////
addChild(b);
var tileObj:Object = new Object();
tileObj.Name = tileSet[counter].Name;
tileObj.Frame = tileSet[counter].Frame;
tileObj.Graphic = tileSet[counter].Graphic;
paletteArray[i].push(tileObj);
setChildIndex(b, 0); //Under grid.
counter++;
}
}
ActivatePaletteListeners();
}
This code works great for a tileSet array that has less than 25 objects. It loops and shows them continuously until it hits 25. I could do without this I guess, but it is a neat affect.
In another class (HandleTiles) I cycle through my tileSet MovieClip and use each frame to create a new object for each tile.
public function GetPaletteTiles(MC:MovieClip)
{
if (tileArray != null)
{
tileArray.length = 0;
}
for(var i:int = 1; i <= MC.totalFrames; i++)
{
MC.gotoAndStop(i); //Change frame for new info.
var tileObj:Object = new Object(); //The object to push to an array of tiles.
var graphicData:BitmapData = new BitmapData(32,32);
graphicData.draw(MC); //Graphic data from sampleTS.
tileObj.Name = MC.currentFrameLabel;
tileObj.Frame = MC.currentFrame;
tileObj.Graphic = graphicData;
tileArray.push(tileObj);
}
BuildIndexArray(15, 20); //Default size 15 x 20.
}
And here I set the tileSet to use
private function ChangeActiveTileset(Mc:MovieClip)
{
activeTileset = Mc;
GetPaletteTiles(activeTileset);
UpdatePalette();
}
I can change the tileSet with a comboBox. That's why I tear down the tileArray every time I call GetPaletteTiles(). Each tileSet is a different MovieClip, like Buildings, Samples, InTheCity, etc.
Sorry I didn't have time to get this code together earlier. Here's tiling code pieces. Because you're using rectangle and you have to stay under max dimensions you have to move the source mc. I think you already know everything else in there.
// set the bmp dimensions to device screensize to prevent exceeding device's max bmp dimensions
if (bStagePortrait) {
iTileWidth = Capabilities.screenResolutionX;
iTileHeight = Capabilities.screenResolutionY;
} else {
iTileWidth = Capabilities.screenResolutionY;
iTileHeight = Capabilities.screenResolutionX;
}
// mcList.mcListVector is the source mc - a regular mc containing mcs, jpgs, dynamic text, vector shapes, etc.
// mcList.mcListBmp is an empty mc
aListTiles = new Array();
iNumberOfTiles = Math.ceil(mcList.height / iTileHeight);
for (i = 0; i < iNumberOfTiles; i++) {
var bmpTile: Bitmap;
// move the source mc
mcList.mcListVector.y = -(i * iTileHeight);
bmpTile = fDrawTile(mcList, 0, 0, iTileWidth, iTileHeight);
mcList.mcListBmp.addChild(bmpTile);
bmpTile.x = 0;
bmpTile.y = (i * iTileHeight);
aListTiles.push(bmpTile);
}
// remove the regular mc
mcList.mcListVector.removeChild(mcList.mcListVector.mcPic);
mcList.mcListVector.mcPic = null;
mcList.removeChild(mcList.mcListVector);
mcList.mcListVector = null;
}
function fDrawTile(pClip: MovieClip, pX: int, pY: int, pWidth: int, pHeight: int): Bitmap {
trace("fDrawTile: " + pX + "," + pY + " " + pWidth + "," + pHeight);
var rectTemp: Rectangle = new Rectangle(pX, pY, pWidth, pHeight);
var bdClip: BitmapData = new BitmapData(pWidth, pHeight, true, 0x00000000);
var bdTemp: BitmapData = new BitmapData(pWidth, pHeight, true, 0x00000000);
bdClip.draw(pClip, null, null, null, rectTemp, true);
bdTemp.copyPixels(bdClip, rectTemp, new Point(0, 0));
var bmpReturn: Bitmap = new Bitmap(bdTemp, "auto", true);
return bmpReturn;
}

actionscript 3.0 visible mask over a visible masked object

I have a moving truck in my game and I want the city lights reflections (NOT the background) to be visible over its body as it moves around.
What stands behind the truck does not matter, some trees and buildings.
So,
I add the background (not important);
then I add the truck to the stage;
then I add another MovieClip with the size of the whole stage (city lights and stuff) and I set it as a masking object for my truck.
I dont want the truck to disappear, i just want the masking object show up over it with some transparency;
I know about masking and also catching my movieclips as bitmaps but it wont work in my case; because here the truck stays totally visible and the mask semi-transparent.
Please help me, I'm running out of time:/
EDIT
Here is my current code based off one of the asnwers:
var buildingHolder: Sprite = new Sprite;
this.addChild(buildingHolder);
var Mask: Sprite = new Sprite()
Mask = Sprite(buildingHolder);
Mask.alpha = 1;
Mask.cacheAsBitmap = true;
this.addChild(Mask);
var reflection: MovieClip = new nightSky1Mask;
reflection.x = 0;
reflection.y = 480;
reflection.alpha = .6;
reflection.scaleX *= 320 / reflection.width;
reflection.scaleY = reflection.scaleX;
reflection.cacheAsBitmap = true;
reflection.mask = Mask;
this.addChild(reflection);
for (var i: int = 0; i <= 29; i++){
//some codes are deleted here
var image: MovieClip = new level1Images[i];
image.x = // deleted
image.y = // deleted
image.scaleX *= 30 / image.width * 2;
image.scaleY *= 5 / image.width * 2;
buildingHolder.addChild(image)
currLevelImages.push(image)
}
You DON'T want to mask the truck. What you want to mask are the city lights.
You need to create a copy of the truck, and mask the city lights with that.
Assuming you have a Bitmap in your library with exported class as TruckImage and your lights are exported for actionscript as Lights, you can do something like this:
var truck:Bitmap = new Bitmap(new TruckImage());
//scale and position however you'd like
truck.scaleX = truck.scaleY = .25;
truck.y = 100;
addChild(truck);
var theMask:Bitmap = new Bitmap(truck.bitmapData);
theMask.cacheAsBitmap = true;//!very important
theMask.scaleX = theMask.scaleY = truck.scaleX;
addChild(theMask); //also important
lights = new Bitmap(new Lights());
lights.cacheAsBitmap = true;//!very important
lights.mask = theMask;
addChild(lights);
//let's move the truck and the mask every frame
addEventListener(Event.ENTER_FRAME,enterFrame);
function enterFrame(e:Event):void {
truck.x = (truck.x + 2) % stage.stageWidth;
theMask.x = truck.x;
}
EDIT
Try something like this: (creating a bitmap copy of your building)
var buildingHolder:Sprite = new Sprite();
this.addChild(buildingHolder);
//create a bitmap data object and draw the building holder sprite into it (making a copy)
var maskBMD:BitmapData = new BitmapData(buildingHolder.width,buildingHolder.height,true,0x00000000);
maskBMD.draw(buildingHolder);
var msk:Bitmap = new Bitmap(maskBMD,"auto",true);
msk.cacheAsBitmap = true;
this.addChild(msk);
var reflection:MovieClip = new nightSky1Mask;
reflection.x = 0;
reflection.y = 480;
reflection.alpha = .6;
reflection.scaleX *= 320 / reflection.width;
reflection.scaleY = reflection.scaleX;
reflection.cacheAsBitmap = true;
reflection.mask = msk;
this.addChild(reflection);
for (var i: int = 0; i <= 29; i++){
//some codes are deleted here
var image: MovieClip = new level1Images[i];
image.x = // deleted
image.y = // deleted
image.scaleX *= 30 / image.width * 2;
image.scaleY *= 5 / image.width * 2;
buildingHolder.addChild(image)
currLevelImages.push(image)
}
Or, you could do something like this to make two copies of your building:
var buildingHolder:Sprite = createBuilding();
var buildingHolderMask:Sprite = createBuilding(false);
function createBuilding(addToArray:Boolean = true):Sprite {
var building:Sprite = new Sprite();
for (var i: int = 0; i <= 29; i++){
//some codes are deleted here
var image: MovieClip = new level1Images[i];
image.x = // deleted
image.y = // deleted
image.scaleX *= 30 / image.width * 2;
image.scaleY *= 5 / image.width * 2;
building.addChild(image)
if(addToArray) currLevelImages.push(image)
}
return building;
}

Get the upper, bottom, rightmost and leftmost point of a pixel-perfect BitmapData collision

How can I get the upper, bottom, rightmost and leftmost point of a pixel-perfect BitmapData collision? This is my collision-detection code:
public static function checkCollision(object1:*, object2:*, debug:Boolean = false):Boolean{
var object1Rect:Rectangle = object1.getRect(stage);
var object2Rect:Rectangle = object2.getRect(stage);
var object1Point:Point = new Point(object1Rect.x, object1Rect.y);
var object2Point:Point = new Point(object2Rect.x, object2Rect.y);
var bitmapData1:BitmapData = new BitmapData(
object1Rect.width,
object1Rect.height,
true,
0
);
var bitmapData2:BitmapData = new BitmapData(
object2Rect.width,
object2Rect.height,
true,
0
);
var clr:ColorTransform = new ColorTransform();
if(debug)
clr.color = 0x00ff00;
bitmapData1.draw(object1, new Matrix(1, 0, 0, 1, -object1Rect.x, -object1Rect.y), clr);
bitmapData2.draw(object2, null, clr);
if(debug){
if(bmp1.stage)
stage.removeChild(bmp1);
bmp1 = new Bitmap(bitmapData1);
bmp1.x = object1Point.x;
bmp1.y = object1Point.y;
stage.addChild(bmp1);
if(bmp2.stage)
stage.removeChild(bmp2);
bmp2 = new Bitmap(bitmapData2);
bmp2.x = object2Point.x;
bmp2.y = object2Point.y;
stage.addChild(bmp2);
}
var bCollide:Boolean = bitmapData1.hitTest(
object1Point,
255,
bitmapData2,
object2Point,
255
);
if(!debug){
bitmapData1.dispose();
bitmapData2.dispose();
}
return bCollide;
}
And it works perfeclty fine. However, the code I use to detect the top hitpoint doesn't work properly. This is the code:
public static function getHitPoint(object1:*, object2:*):Point{
var point:Point = new Point();
var object1Rect:Rectangle = object1.getRect(stage);
var object2Rect:Rectangle = object2.getRect(stage);
var object1Point:Point = new Point(object1Rect.x, object1Rect.y);
var object2Point:Point = new Point(object2Rect.x, object2Rect.y);
var bitmapData1:BitmapData = new BitmapData(
object1.width,
object1.height,
true,
0
);
var bitmapData2:BitmapData = new BitmapData(
object2.width,
object2.height,
true,
0
);
bitmapData1.draw(object1, new Matrix(1, 0, 0, 1, -object1Rect.x, -object1Rect.y));
bitmapData2.draw(object2);
var bitmap1:Bitmap = new Bitmap(bitmapData1);
var bitmap2:Bitmap = new Bitmap(bitmapData2);
bitmap1.x = object1Point.x;
bitmap1.y = object1Point.y;
bitmap2.x = object2Point.x;
bitmap2.y = object2Point.y;
var bitmapOrigin:Point = new Point(object1Point.x, object1Point.y);
var bitmap2OriginLocal:Point = bitmap2.globalToLocal(bitmapOrigin);
var overlappingPixels:Vector.<uint> = bitmap2.bitmapData.getVector(
new Rectangle(bitmap2OriginLocal.x, bitmap2OriginLocal.y, object1Rect.width, object1Rect.height)
);
for(var i:String in overlappingPixels){
var index:uint = uint(i);
if(overlappingPixels[i] != 0){
point.x = (index % object1.width) + (bitmap2.x > bitmap1.x ? bitmap2.x : bitmap1.x);
point.y = (uint(index / bitmap1.height)) + (bitmap2.y > bitmap1.y ? bitmap2.y : bitmap1.y);
break;
}
}
return point;
}
I've got no idea why, but the getHitPoint() function sometimes returns the wrong coordinates. Can anyone please explain why that is? And how can I detect the bottommost, the leftmost and the rightmost hitpoint?
Edit
I now know why getHitPoint() sometimes returned a wrong value: point.y = (uint(index / bitmap1.height)) + (bitmap2.y > bitmap1.y ? bitmap2.y : bitmap1.y); should be point.y = (uint(index/bitmap1.width)) + (bitmap2.y > bitmap1.y ? bitmap2.y : bitmap1.y);
Edit 2
I found out how to get the bottom hitpoint:
public static function getHitPoint(object1:*, object2:*, direction:int = 0):*{
var point:Point = new Point();
var object1Rect:Rectangle = object1.getRect(stage);
var object2Rect:Rectangle = object2.getRect(stage);
var object1Point:Point = new Point(object1Rect.x, object1Rect.y);
var object2Point:Point = new Point(object2Rect.x, object2Rect.y);
var bitmapData1:BitmapData = new BitmapData(
Math.round(object1Rect.width),
Math.round(object1Rect.height),
true,
0
);
var bitmapData2:BitmapData = new BitmapData(
Math.round(object2Rect.width),
Math.round(object2Rect.height),
true,
0
);
bitmapData1.draw(object1, new Matrix(1, 0, 0, 1, -object1Rect.x, -object1Rect.y));
bitmapData2.draw(object2);
var bitmap1:Bitmap = new Bitmap(bitmapData1);
var bitmap2:Bitmap = new Bitmap(bitmapData2);
bitmap1.x = object1Point.x;
bitmap1.y = object1Point.y;
bitmap2.x = object2Point.x;
bitmap2.y = object2Point.y;
var bitmapOrigin:Point = new Point(object1Point.x, object1Point.y);
var bitmap2OriginLocal:Point = bitmap2.globalToLocal(bitmapOrigin);
var overlappingPixels:Vector.<uint> = bitmap2.bitmapData.getVector(
new Rectangle(bitmap2OriginLocal.x, bitmap2OriginLocal.y, object1Rect.width, object1Rect.height)
);
switch(direction){
case 0: //top
for(var i:String in overlappingPixels){
var index:uint = uint(i);
if(overlappingPixels[i] != 0){
point.x = (index % bitmap1.width) + (bitmap2.x > bitmap1.x ? bitmap2.x : bitmap1.x);
point.y = (uint((index)/bitmap1.width)) + (bitmap2.y > bitmap1.y ? bitmap2.y : bitmap1.y);
return point;
}
}
case 1: //right
// I still need this
case 2: //bottom
overlappingPixels.reverse();
for(var i:String in overlappingPixels){
var index:uint = uint(i);
if(overlappingPixels[i] != 0){
point.x = bitmap1.width - (index % bitmap1.width) + (bitmap2.x > bitmap1.x ? bitmap2.x : bitmap1.x);
point.y = (bitmap2.y + bitmap2.height > bitmap1.y + bitmap1.height ? bitmap1.y + bitmap1.height : bitmap2.y + bitmap2.height) - (uint(index/bitmap1.width));
return point;
}
}
case 3: //left
// I still need this too
}
return false;
}
I still need a way to get the left and rightmost hitpoints though
You don't need to do it like you're doing there. You can do it all within a single function, which returns everything back correctly. I've added comments to the below. Please take note of what I've changed, as when you're trying to do it as you're doing now, with the code you changed, it is impossible.
This works for any shape, any direction. It'll give you the exact X and Y of the collision.
Please do not make this into a static function. Put it into a global class and use a Singleton to manage it instead. Things start to go very badly wrong when you being using static functions and reference the stage.
Also, if you're going to be working with pixel values of less than 1 (ie 99.75), the below will need a bit of adapting to cater for that. I've assumed you're using whole pixels, given your Math.round usage.
/**
*
* #param object1
* #param object2
* #return
*/
private function getHitPoint(object1:*, object2:*):*{
var point:Point;
// X and Y where we hit
// do NOT change this to a stage location or it does NOT work
var object1Point:Point = new Point(object1.x, object1.y);
var object2Point:Point = new Point(object2.x, object2.y);
var bitmapData1:BitmapData = new BitmapData(
Math.round(object1.width),
Math.round(object1.height),
true,
0
);
var bitmapData2:BitmapData = new BitmapData(
Math.round(object2.width),
Math.round(object2.height),
true,
0
);
// Draw
bitmapData1.draw(object1, new Matrix(1, 0, 0, 1, -object1.x, -object1.y));
bitmapData2.draw(object2);
// Create BMP's
var bitmap1:Bitmap = new Bitmap(bitmapData1);
var bitmap2:Bitmap = new Bitmap(bitmapData2);
// Set X and Y and BMP
bitmap1.x = object1Point.x;
bitmap1.y = object1Point.y;
bitmap2.x = object2Point.x;
bitmap2.y = object2Point.y;
// BMP origin is the object1 X and Y
var bitmapOrigin:Point = new Point(object1Point.x, object1Point.y);
// Create a local version of the bitmap2 so we can see what is overlapping
var bitmap2OriginLocal:Point = bitmap2.globalToLocal(bitmapOrigin);
// Create a rectangle from what we now know
var rect:Rectangle = new Rectangle(bitmap2OriginLocal.x, bitmap2OriginLocal.y, object1.width, object1.height);
// The overlapping pixels are within the rectangle, so get them all
var overlappingPixels:Vector.<uint> = bitmap2.bitmapData.getVector(rect);
// Run through all the overlapping pixels until we find a colourful one
for (var i:uint = 0; i < overlappingPixels.length; i++ ) {
var index:uint = overlappingPixels[i];
// If the colour is not 0, we have found it
if(index != 0){
point = new Point();
// Basically, instead of using width and getting 100, we're working out how
// many pixles across the overlap is. The Vector doesn't tell us this, so we need to work it out
var overlappingWidth:uint = object1.width - Math.abs(bitmap2OriginLocal.x);
// The Y is object1.y, minus the local y, plus object1's width minus the X from the local
point.y = object1.y - bitmap2OriginLocal.y + uint(i / overlappingWidth);
// The X is the same as above, but % of the width
point.x = object1.x - bitmap2OriginLocal.x + (i % overlappingWidth);
// Found it, we're done
break;
}
}
// Only fires when you've got a collision that is less than 1 pixel from the width or height
// Just a fail safe
if (!point) {
point = new Point(object1.width, object1.height);
}
return point;
}
For context, my entire class is below which shows how I was using this function. You can copy/paste this class and it will work. It shows how you move sprites around the screen, once it finds a collision, then it works out where the collision took place.
This class is for absolute pixel perfect collision detection, including an example.
package kazo
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.geom.Matrix;
/**
* ...
* #author KM
*/
public class TestCases2 extends Sprite
{
private var rect :Sprite;
private var circle :Sprite;
/**
*
*/
public function TestCases2()
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
public function init(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
trace('Starting test case');
// Rectangle
rect = new Sprite();
// Circle
circle = new Sprite();
// Draw the rectangle. Center point must be TOP LEFT
// If you're using Flash Professional, place everything at 0,0 inside the MC
rect.graphics.beginFill(0xff0000);
rect.graphics.drawRect(0, 0, 100, 100);
rect.graphics.endFill();
// Draw the circle. Center point is TOP LEFT, so the X and Y of the circle need to be equal to the radius
circle.graphics.beginFill(0xffff00);
circle.graphics.drawCircle(50, 50, 50);
circle.graphics.endFill();
// Add them
addChild(rect);
addChild(circle);
// Position
rect.x = 225;
rect.y = 75;
// Position
circle.x = 225;
circle.y = 225;
// Frame loop
addEventListener(Event.ENTER_FRAME, frameFunc);
}
/**
*
* #param e
*/
private function frameFunc(e:Event):void {
// move them around
circle.y -= 2;
circle.x += 0;
rect.y += 1;
rect.x += 0;
// Check for collisions. If found, stop. Pass 'true' as the final param if you want it to draw to the screen
if (checkCollision(rect, circle)) {
var ref:Point = getHitPoint(rect, circle);
// Draws where the collision hit
var loc:Sprite = new Sprite();
loc.graphics.beginFill(0x000000);
loc.graphics.drawRect(0, 0, 10, 10);
loc.graphics.endFill();
addChild(loc);
loc.x = ref.x;
loc.y = ref.y;
trace(ref);
removeEventListener(Event.ENTER_FRAME, frameFunc);
}
}
/**
*
* #param _obj1
* #param _obj2
* #param _debug
* #return
*/
private function checkCollision(_obj1:Sprite, _obj2:Sprite, _debug:Boolean = false):Boolean {
// Draw the first item to bitmapdata
var bmd1:BitmapData = new BitmapData(_obj1.width, _obj1.height, true, 0);
// ..and the second
var bmd2:BitmapData = new BitmapData(_obj2.width, _obj2.height, true, 0);
// Now draw them
bmd1.draw(_obj1);
bmd2.draw(_obj2);
// If we're in debug, also add the bitmap to the stage so we can see where we are
if (_debug) {
var bmp:Bitmap = new Bitmap(bmd1);
bmp.x = _obj1.x;
bmp.y = _obj1.y;
addChild(bmp);
var bmp2:Bitmap = new Bitmap(bmd2);
bmp2.x = _obj2.x;
bmp2.y = _obj2.y;
addChild(bmp2);
}
// Hit test including alpha channel. Obj1 X/Y, Obj2 X/Y, alpha channel
var rtn:Boolean = bmd1.hitTest(new Point(_obj1.x, _obj1.y), 255, bmd2, new Point(_obj2.x, _obj2.y), 255);
// Dispose the bitmap data, we dont need it anymore
if (!_debug) {
bmd1.dispose();
bmd2.dispose();
}
// Return the boolean
return rtn;
}
/**
*
* #param object1
* #param object2
* #return
*/
private function getHitPoint(object1:*, object2:*):*{
var point:Point;
// X and Y where we hit
// do NOT change this to a stage location or it does NOT work
var object1Point:Point = new Point(object1.x, object1.y);
var object2Point:Point = new Point(object2.x, object2.y);
var bitmapData1:BitmapData = new BitmapData(
Math.round(object1.width),
Math.round(object1.height),
true,
0
);
var bitmapData2:BitmapData = new BitmapData(
Math.round(object2.width),
Math.round(object2.height),
true,
0
);
// Draw
bitmapData1.draw(object1, new Matrix(1, 0, 0, 1, -object1.x, -object1.y));
bitmapData2.draw(object2);
// Create BMP's
var bitmap1:Bitmap = new Bitmap(bitmapData1);
var bitmap2:Bitmap = new Bitmap(bitmapData2);
// Set X and Y and BMP
bitmap1.x = object1Point.x;
bitmap1.y = object1Point.y;
bitmap2.x = object2Point.x;
bitmap2.y = object2Point.y;
// BMP origin is the object1 X and Y
var bitmapOrigin:Point = new Point(object1Point.x, object1Point.y);
// Create a local version of the bitmap2 so we can see what is overlapping
var bitmap2OriginLocal:Point = bitmap2.globalToLocal(bitmapOrigin);
// Create a rectangle from what we now know
var rect:Rectangle = new Rectangle(bitmap2OriginLocal.x, bitmap2OriginLocal.y, object1.width, object1.height);
// The overlapping pixels are within the rectangle, so get them all
var overlappingPixels:Vector.<uint> = bitmap2.bitmapData.getVector(rect);
// Run through all the overlapping pixels until we find a colourful one
for (var i:uint = 0; i < overlappingPixels.length; i++ ) {
var index:uint = overlappingPixels[i];
// If the colour is not 0, we have found it
if(index != 0){
point = new Point();
// Basically, instead of using width and getting 100, we're working out how
// many pixles across the overlap is. The Vector doesn't tell us this, so we need to work it out
var overlappingWidth:uint = object1.width - Math.abs(bitmap2OriginLocal.x);
// The Y is object1.y, minus the local y, plus object1's width minus the X from the local
point.y = object1.y - bitmap2OriginLocal.y + uint(i / overlappingWidth);
// The X is the same as above, but % of the width
point.x = object1.x - bitmap2OriginLocal.x + (i % overlappingWidth);
// Found it, we're done
break;
}
}
// Only fires when you've got a collision that is less than 1 pixel from the width or height
// Just a fail safe
if (!point) {
point = new Point(object1.width, object1.height);
}
return point;
}
}
}

node.js canvas Image as a 'background'

it possible to 'fillpattern in images' using node.js npm canvas ?
I tried following way.but i got the error
return new CanvasPattern(image);
^
Error: Image given has not completed loading.
exports.convertImg = function(story){
var Canvas = require('canvas')
, canvas = new Canvas(200,200)
, ctx = canvas.getContext('2d'),textDimensions, img = new Canvas.Image;
var textWidth = ctx.measureText(story).width;
img.src = "/images/fillimage.png";
var buffer = new Buffer(story, "base64"),length=buffer.length;
var pat=ctx.createPattern(img,"repeat");
ctx.fillStyle = pat;
ctx.font = "20px verdana";
var x= (canvas.width -200) / 2;
var y= 60;
wrapText(ctx,story,x,y,200,200);
var imges = canvas.toDataURL();
var data = imges.replace(/^data:image\/\w+;base64,/, "");
var buf = new Buffer(data, 'base64');
var length=buf.length;
return images;
}
how can i fill background images in canvas fillpattern. plz help me.
Thanks.

ActionScript3 - Remove bitmap and bitmapData

How to remove the bitmap from the holder and the bitmapData from the Flash Player memory?
var _myThumb:Bitmap;
var _myThumbData:BitmapData;
var bitmap:Bitmap
//
function createThumbs()
{
_myThumbData = new BitmapData(pic.picdefault.width,pic.picdefault.height,false,0xffffff);
//
picthumbs.t1.holder.addChild(createBitmap(_myThumbData));
picthumbs.t2.holder.addChild(createBitmap(_myThumbData));
picthumbs.t3.holder.addChild(createBitmap(_myThumbData));
picthumbs.t4.holder.addChild(createBitmap(_myThumbData));
picthumbs.t5.holder.addChild(createBitmap(_myThumbData));
}
function createBitmap(bmd:BitmapData):Bitmap
{
var bitmap:Bitmap = new Bitmap(bmd);
bitmap.smoothing = true;
setSize(bitmap, bmd.width, bmd.height, 94, 94);
return bitmap;
}
function setSize(target:DisplayObject, contentWidth:Number, contentHeight:Number, targetWidth:Number, targetHeight:Number):void {
var w:Number = targetWidth;
var h:Number = targetHeight;
var containerRatio:Number = targetWidth / targetHeight;
var imageRatio:Number = contentWidth / contentHeight;
if (containerRatio < imageRatio) h = w / imageRatio;
else w = h * imageRatio;
target.width = w;
target.height = h;
target.x = (targetWidth - w) * .5;
target.y = (targetHeight -h) * .5;
}
//
function createThumbnail()
{
_myThumbData.draw(pic.picdefault);
}
Assuming the holder is just an empty MovieClip then you can simply go:
picthumbs.t1.holder.removeChildAt(0);
This will remove the reference to the Bitmap thereby making it eligible for garbage collection. As the BitmapData is only referenced by the Bitmap, and the Bitmap is no longer referenced, then it too will be removed from memory.
Look into BitmapData.dispose().