/**
* Copyright broneri ( http://wonderfl.net/user/broneri )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/emh8
*/
/*
2011/09/01
Kyungmin Cho
broneri@gmail.com
thinning test : Zhang Suen algorithm
--------------------------------------
2011-09-01 - initial code.
2011-09-07 - bug fix. thanks to kevin.
*/
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.display.*;
public class FlashTest extends Sprite {
private var img_width:int = 20;
private var img_height:int = 20;
private var img:Array = new Array (
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0],
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0],
[0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0],
[0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0],
[0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0],
[0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0],
[0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
);
private var img_triangle:Array = new Array (
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0],
[0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0],
[0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0],
[0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0],
[0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0],
[0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0],
[0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
);
private var _bitmap:BitmapData= new BitmapData(stage.stageWidth, stage.stageHeight,
false, 0xff000000);
private var _image:Bitmap= new Bitmap(_bitmap);
private var org_img:Array;
private var org_img_triangle:Array;
public function FlashTest() {
// write as3 code here..
addChild( _image );
org_img = make_bitmap_array( img_width, img_height );
copy_bitmap_array( img, org_img, img_width, img_height );
thin_image ( img, img_width, img_height );
org_img_triangle = make_bitmap_array( img_width, img_height );
copy_bitmap_array( img_triangle, org_img_triangle, img_width, img_height );
thin_image ( img_triangle, img_width, img_height );
addEventListener( Event.ENTER_FRAME, onEnterFrame );
}
public function onEnterFrame (event:Event) : void {
// original image
draw_image ( org_img, img_width, img_height, 100, 50 );
// thining image
draw_image ( img, img_width, img_height, 200, 50 );
// original image
draw_image ( org_img_triangle, img_width, img_height, 100, 150 );
// thining image
draw_image ( img_triangle, img_width, img_height, 200, 150 );
}
public function draw_image ( img_src:Array, w:int, h:int, xpos:int, ypos:int ) : void {
for ( var x:int = 0 ; x < w; x ++ ) {
for ( var y:int = 0 ; y < h; y ++ ) {
var col:int;
if ( img_src[y][x] == 1 )
col = 0x00ffffff;
else
col = 0x00000000;
_bitmap.setPixel( xpos +x, ypos +y, col );
}
}
}
public function thin_pixel_common ( s:Array, x:int, y:int ) : int {
// pixel removal condition
// 1. pixel is black
if ( s[y][x] == 0 )
return 0;
var near:Array = new Array(
s[y-1][x-1], s[y-1][x], s[y-1][x+1], s[y][x+1],
s[y+1][x+1], s[y+1][x], s[y+1][x-1], s[y][x-1], s[y-1][x-1]
);
var count: int = 0;
var connect:int = 0;
for( var i:int = 0; i <= 7; i++ ) {
if( near[i] == 1 ) count ++;
if( near[i] == 1 && near[i+1] == 0 ) connect ++;
}
// 2. near pixels
// check black pixels are >=2 and <=6
if ( count >= 2 && count <= 6 &&
// 3. connectivity is 1
connect == 1 )
return 1;
return 0;
}
public function thin_pixel_loop1 ( s:Array, x:int, y:int ) : int {
if ( thin_pixel_common ( s, x, y ) == 0 )
return 0;
if ( (s[y][x-1] == 0 || s[y-1][x] == 0 || s[y][x+1] == 0) &&
(s[y-1][x] == 0 || s[y][x+1] == 0 || s[y+1][x] == 0) ) {
return 1;
}
return 0;
}
public function thin_pixel_loop2 ( s:Array, x:int, y:int ) : int {
if ( thin_pixel_common ( s, x, y ) == 0 )
return 0;
if ( (s[y][x-1] == 0 || s[y+1][x] == 0 || s[y][x+1] == 0) &&
(s[y-1][x] == 0 || s[y][x-1] == 0 || s[y+1][x] == 0) ) {
return 1;
}
return 0;
}
public function thin_loop1 ( img_src:Array, width:int, height:int ) : int {
var del:Array;
del = make_bitmap_array( width, height );
var thin_flag:int = 0;
var y:int = 1;
var x:int = 1;
for ( y = 1; y < height-1; y++ ) {
for ( x = 1; x < width-1; x++ ) {
if ( thin_pixel_loop1( img_src, x,y ) == 1 ) {
del [y][x] = 1;
}
}
}
thin_flag = del_bitmap_array ( img_src, del, width, height );
return thin_flag;
}
public function thin_loop2 ( img_src:Array, width:int, height:int ) : int {
var del:Array;
del = make_bitmap_array( width, height );
var thin_flag:int = 0;
var y:int = 1;
var x:int = 1;
for ( y = 1; y < height-1; y++ ) {
for ( x = 1; x < width-1; x++ ) {
if ( thin_pixel_loop2( img_src, x,y ) == 1 ) {
del [y][x] = 1;
}
}
}
thin_flag = del_bitmap_array ( img_src, del, width, height );
return thin_flag;
}
public function del_bitmap_array ( src:Array, del:Array, width:int, height:int ) : int {
var thin_flag:int = 0;
var y:int = 1;
var x:int = 1;
for ( y = 1; y < height-1; y++ ) {
for ( x = 1; x < width-1; x++ ) {
if ( del [y][x] == 1 ) {
src[y][x] = 0;
thin_flag = 1;
}
}
}
return thin_flag;
}
public function make_bitmap_array ( width:int, height:int ) : Array {
var y:int = 0;
var x:int = 0;
var arr:Array = new Array(height);
for ( y = 0; y < height; y ++ ) {
arr[y] = new Array(width);
for ( x = 0; x < width; x ++ ) {
arr[y][x] = 0;
}
}
return arr;
}
public function copy_bitmap_array ( s:Array, d:Array, width:int, height:int ) : void {
var y:int = 0;
var x:int = 0;
for ( y = 0; y < height; y ++ ) {
for ( x = 0; x < width; x ++ ) {
d[y][x] = s[y][x];
}
}
}
// thining algorithm : Zhang Suen
public function thin_image ( img_src:Array, width:int, height:int ) : void {
var cont : int = 1;
while (cont) {
cont = 0;
if ( thin_loop1( img_src, width, height ) == 1 )
cont = 1;
if ( thin_loop2( img_src, width, height ) == 1 )
cont = 1;
}
}
}
}