Drawing outlines around organic shapes
- by ThunderChunky_SF
One thing that seems particularly easy to do in the Flash IDE but difficult to do with code is to outline an organic shape. In the IDE you can just use the inkbucket tool to draw a stroke around something. Using nothing but code it seems much trickier. One method I've seen is to add a glow filter to the shape in question and just mess with the strength. But what if i want to only show the outline?
What I'd like to do is to collect all of the points that make up the edge of the shape and then just connect the dots. I've actually gotten so far as to collect all of the points with a quick and dirty edge detection script that I wrote. So now I have a Vector of all the points that makeup my shape. How do I connect them in the proper sequence so it actually looks like the original object?
For anyone who is interested here is my edge detection script:
// Create a new sprite which we'll use for our outline
var sp:Sprite = new Sprite();
var radius:int = 50;
sp.graphics.beginFill(0x00FF00, 1);
sp.graphics.drawCircle(0, 0, radius);
sp.graphics.endFill();
sp.x = stage.stageWidth / 2;
sp.y = stage.stageHeight / 2;
// Create a bitmap data object to draw our vector data
var bmd:BitmapData = new BitmapData(sp.width, sp.height, true, 0);
// Use a transform matrix to translate the drawn clip so that none of its
// pixels reside in negative space. The draw method will only draw starting
// at 0,0
var mat:Matrix = new Matrix(1, 0, 0, 1, radius, radius);
bmd.draw(sp, mat);
// Pass the bitmap data to an actual bitmap
var bmp:Bitmap = new Bitmap(bmd);
// Add the bitmap to the stage
addChild(bmp);
// Grab all of the pixel data from the bitmap data object
var pixels:Vector.<uint> = bmd.getVector(bmd.rect);
// Setup a vector to hold our stroke points
var points:Vector.<Point> = new Vector.<Point>;
// Loop through all of the pixels of the bitmap data object and
// create a point instance for each pixel location that isn't
// transparent.
var l:int = pixels.length;
for(var i:int = 0; i < l; ++i)
{
// Check to see if the pixel is transparent
if(pixels[i] != 0)
{
var pt:Point;
// Check to see if the pixel is on the first or last
// row. We'll grab everything from these rows to close the outline
if(i <= bmp.width || i >= (bmp.width * bmp.height) - bmp.width)
{
pt = new Point();
pt.x = int(i % bmp.width);
pt.y = int(i / bmp.width);
points.push(pt);
continue;
}
// Check to see if the current pixel is on either extreme edge
if(int(i % bmp.width) == 0 || int(i % bmp.width) == bmp.width - 1)
{
pt = new Point();
pt.x = int(i % bmp.width);
pt.y = int(i / bmp.width);
points.push(pt);
continue;
}
// Check to see if the previous or next pixel are transparent,
// if so save the current one.
if(i > 0 && i < bmp.width * bmp.height)
{
if(pixels[i - 1] == 0 || pixels[i + 1] == 0)
{
pt = new Point();
pt.x = int(i % bmp.width);
pt.y = int(i / bmp.width);
points.push(pt);
}
}
}
}