※現在、「wonderfl build flash online」求人コンテンツ制作に関してのアンケートを実施中です!みなさまのお力添えを頂いて、続々とアンケート結果が集まっていますが、まだまだ募集しております。ご協力のほど、どうぞよろしくお願いいたします!
wonderfl運営事務局
→アンケートページ(※ログインしてからお答えいただけるようになっています。)
avatarsspaceinvaderspngtext
イカス!
インベーダースバラスィです!
Cool
i like it
面白い。ARのマーカーにしたいかも。
コードもすごいけど、発想も面白い
retro
おおー
あばたもえくぼ
おもろいw
仕事はや!
Retro Avatars forked from: Retro Avatars
- // forked from miyaoka's Retro Avatars
- /*
- =======================================
- Retro Avatars for Flash
- =======================================
- -Type avatar name to generate image.
- -press ENTER key to save current image as PNG.
- // Retro Avatars
- // -------------
- // By Richard Phipps
- // (Open source, but a credit if used would be nice!)
- http://retroremakes.com/forum/index.php/topic,657.0.html
- より移植してみました
- [Sample]
- http://www.indiegames.com/blog/2009/06/freeware_app_pick_retro_avatar.html
- http://www.flickr.com/photos/miyaoka/3592194889/
- */
- package
- {
- import flash.display.Sprite;
- import flash.text.TextField;
- import flash.text.TextFormat;
- import flash.text.TextFormatAlign;
- import flash.text.TextFieldType;
- import flash.text.TextFieldAutoSize;
- import flash.ui.Keyboard;
- import flash.events.KeyboardEvent;
- import flash.display.Bitmap;
- import flash.display.BitmapData;
- import flash.utils.ByteArray;
- import com.adobe.images.PNGEncoder;
- import flash.net.FileReference;
- import flash.geom.Matrix;
- import flash.system.Capabilities;
- import flash.system.IME;
- [SWF(width="465", height="465", backgroundColor= 0x0, frameRate="60")]
- public class RetroAvatars
- extends Sprite
- {
- private var tfd:TextField = new TextField();
- private var maxNameLength:uint = 9;
- private var bmd:AvatarBMD = new AvatarBMD(12, 12, false);
- private var bmd32:BitmapData = new BitmapData(bmd.width, bmd.height, true, 0x0);
- private var bmp:Bitmap = new Bitmap(bmd32);
- private static const EYES_COL:int = 0;
- private static const NOSE_COL:int = 0;
- private static const MOUSE_COL:int = 0;
- private var isFirst:Boolean = true;
- public function RetroAvatars():void
- {
- //bg
- graphics.beginFill(0);
- graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
- //ime off
- if (Capabilities.hasIME)
- {
- try
- {
- IME.enabled = false;
- }
- catch (e:Error) {}
- }
- //bmp
- bmp.scaleX = bmp.scaleY = 24;
- bmp.x = (stage.stageWidth - bmp.width) / 2;
- bmp.y = 40;
- addChild(bmp);
- //text
- var tft:TextFormat = new TextFormat();
- tft.align = TextFormatAlign.CENTER;
- tft.bold = true;
- tft.font = "Verdana";
- tft.letterSpacing = 5;
- tft.size = 48;
- tfd.defaultTextFormat = tft;
- tfd.autoSize = TextFieldAutoSize.CENTER;
- tfd.x = 465/2;
- tfd.y = 380;
- tfd.text = "ENTER NAME";
- tfd.textColor = 0xDDDDDD;
- isFirst = true;
- addChild(tfd);
- //event
- stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
- }
- private function keyDownHandler(e:KeyboardEvent):void
- {
- var cc:uint = e.charCode;
- // lower case keys, so make upper case.
- if (97 <= cc && cc <= 122) cc -= 32;
- if (isFirst) tfd.text = ""; isFirst = false;
- if (
- tfd.length < maxNameLength &&
- (
- cc == 32 // Space
- || (cc >= 65 && cc <= 90) //letters
- || (cc >= 48 && cc <= 57) //numbers
- )
- )
- {
- tfd.text = tfd.text.concat(String.fromCharCode(cc));
- }
- else if ( cc == 8 && tfd.length > 0) //Backspace
- {
- tfd.text = tfd.text.substr(0, tfd.length -1);
- }
- else if (cc == 13 && 0 < tfd.text.length) // ENTER key
- {
- //save PNG to local
- var mtx:Matrix = new Matrix();
- var sc:Number = 8;
- mtx.scale(sc, sc);
- var tempBmd:BitmapData = new BitmapData(bmd32.width * sc, bmd32.height * sc, true,0);
- tempBmd.draw(bmd32, mtx);
- var ba:ByteArray = PNGEncoder.encode(tempBmd);
- var fr:FileReference = new FileReference;
- fr.save(ba, tfd.text + ".png");
- }
- var nameLen:int = tfd.text.length;
- if (nameLen == 0)
- {
- bmd32.fillRect(bmd32.rect, 0);
- return;
- }
- // ------------
- // make code from text and set to srand
- Crand.srand(0);
- var code:int = 0;
- for (var g:int = 0; g < 32; g++)
- {
- code += tfd.text.charCodeAt(g % nameLen) * Crand.rand() % 1024;
- }
- Crand.srand(code); // Seed random generator with code.
- //make avatar color. Random (but not too dark) colour.
- var col:int =
- Crand.rand() % 192 + 64
- | Crand.rand() % 192 + 64 << 8
- | Crand.rand() % 192 + 64 << 16;
- tfd.textColor = col;
- // ------------
- // build avatar img
- bmd.build();
- bmd.removeNoise(0);
- bmd.mirror();
- bmd.enhanceFace();
- //copy to 32bit bmd and set color
- bmd32.threshold(bmd, bmd.rect, bmd.rect.topLeft, ">=", 0xff << 24 | AvatarBMD.SOLID_COL, 0xFF <<24 | col);
- bmd32.threshold(bmd, bmd.rect, bmd.rect.topLeft, "==", 0xff << 24 | AvatarBMD.EYES_COL, EYES_COL);
- bmd32.threshold(bmd, bmd.rect, bmd.rect.topLeft, "==", 0xff << 24 | AvatarBMD.NOSE_COL, NOSE_COL);
- bmd32.threshold(bmd, bmd.rect, bmd.rect.topLeft, "==", 0xff << 24 | AvatarBMD.MOUSE_COL, MOUSE_COL);
- bmd32.threshold(bmd, bmd.rect, bmd.rect.topLeft, "==", 0xff << 24 | AvatarBMD.BLANK_COL, 0);
- }
- }
- }
- import flash.display.BitmapData
- import flash.geom.Matrix;
- import flash.geom.Rectangle;
- class AvatarBMD
- extends BitmapData
- {
- public static const EYES_COL:int = 1;
- public static const NOSE_COL:int = 2;
- public static const MOUSE_COL:int = 3;
- public static const SOLID_COL:int = 0xFF;
- public static const BLANK_COL:int = 0x0;
- public function AvatarBMD(width:int, height:int, transparent:Boolean = true, fillColor:uint = 0xFFFFFFFF):void
- {
- //bmd24
- super(width, height, false, fillColor);
- }
- public function build():void
- {
- var c:int = 158;
- for (var y:int = 0; y < height; y++)
- {
- for (var x:int = 0; x < width; x++)
- {
- setPixel(x, y, (Crand.rand() % 356 > c) ? BLANK_COL : SOLID_COL);
- }
- }
- }
- public function enhanceFace():void
- {
- var eyes:Boolean;
- var nose:Boolean;
- var mouth:Boolean;
- var x:int;
- var y:int;
- var hx:int = width / 2 - 1; // Half width of sprite variable.
- // Detect eyes one pixel away from horizontal centre (look from just below the top edge to the middle of the vertical height).
- for (y = 1; y < height / 2; y++)
- {
- if (getPixel(hx - 1, y) == BLANK_COL) // 0 - Empty, Pixel?
- {
- floodFill(hx - 1, y, EYES_COL); // Mark area with reserved colour 1 (normal colours are 0 - empty & 255 - solid).
- if (checkForFilledEdge() == 0) break; // If this eye area doesn't touch the edges of the image, then stop searching.
- floodFill(hx - 1, y, BLANK_COL); // It reaches the edge, so refill as 0 - empty and keep looking.
- }
- if (getPixel(hx - 2, y) == BLANK_COL) // Any potential eye areas one pixel further away?
- {
- floodFill(hx - 2, y, EYES_COL);
- if (checkForFilledEdge() == 0) break;
- floodFill(hx - 2, y, BLANK_COL);
- }
- }
- // Ok, we didn't find anything!
- if ( y == height / 2)
- {
- // Try to make eyes from any centre pixels (converting them to one pixel further away. i.e. xx -> x x
- for ( y = 1; y < height; y++)
- {
- if (getPixel(hx - 1, y) == SOLID_COL && getPixel(hx, y) == BLANK_COL)
- {
- setPixel(hx - 1, y, BLANK_COL);
- setPixel(hx, y, SOLID_COL);
- setPixel(hx - 1, y + 1, BLANK_COL); // Make the eye 2 pixels (at least) high.
- floodFill(hx - 1, y, EYES_COL);
- if (checkForFilledEdge() == 0) break;
- floodFill(hx - 1, y, BLANK_COL);
- }
- }
- }
- var ny:int = y + 1;
- if (y < height) eyes = true; // Ok, we did find eyes
- // Still NO eyes.
- if (!eyes)
- {
- // Ok, create fake eyes!
- y = 1 + Crand.rand() % (height / 2);
- setPixel(hx - 1, y, EYES_COL);
- outlineArea(1); // Outline to protect area.
- eyes = true;
- ny = y + 1;
- }
- // Remove any joined up eyes (i.e xx instead of x x)
- for (y = 1; y < height; y++)
- {
- if (getPixel(hx, y) == EYES_COL)
- {
- setPixel(hx, y, SOLID_COL);
- setPixel(hx - 1, y, EYES_COL);
- }
- else
- {
- if (getPixel(hx - 2, y) == EYES_COL) setPixel(hx, y, SOLID_COL);
- if (getPixel(hx - 1, y) == EYES_COL) setPixel(hx, y, SOLID_COL);
- }
- }
- mirror(); // Miror all eye work.
- if (eyes) outlineArea(EYES_COL); // Protect eyes with solid outline.
- trace(ny);
- // -------
- // Detect nose
- for (y = ny; y < height; y++)
- {
- if (getPixel(hx, y) == BLANK_COL)
- {
- floodFill(hx, y, NOSE_COL); // Fill with area colour 2.
- if ( checkForFilledEdge() == 0) break;
- floodFill(hx, y, BLANK_COL);
- }
- }
- if ( y < 10) nose = true;
- // No nose?
- if (!nose)
- {
- // Ok, we won't find a mouth either, but we need to make a nose/mouth one out of any open sections (regardless of touching the edge)
- for (y = ny; y < height - 1; y++)
- {
- if (getPixel(hx, y) == BLANK_COL)
- {
- setPixel(hx, y, NOSE_COL)
- nose = true;
- break;
- }
- }
- // Try to find a nose/mouth one pixel away which we can join up. i.e. x x -> xxxx
- if (!nose)
- {
- for (y = ny; y < height - 1; y++)
- {
- if (getPixel(hx - 1, y) == BLANK_COL)
- {
- setPixel(hx -1, y, NOSE_COL)
- setPixel(hx, y, NOSE_COL)
- nose = true;
- break;
- }
- }
- // Ok, NOTHING, just create fake mouth/nose!
- if (!nose)
- {
- y = ny + 1 + Crand.rand() % (height / 3);
- if (y > height - 2) y = height - 2;
- setPixel(hx, y, NOSE_COL)
- nose = true;
- ny = y + 1;
- }
- }
- }
- else
- {
- ny = y + 1;
- // --------
- // Detect mouth
- for (y = ny; y < height; y++)
- {
- if (getPixel(hx, y) == BLANK_COL)
- {
- floodFill(hx, y, MOUSE_COL);
- if (checkForFilledEdge() == 0) break;
- floodFill(hx, y, BLANK_COL);
- }
- }
- if (y < height) mouth = true;
- if (!mouth) // Still no mouse, so look one pixel further away and then if found, join up.
- {
- for (y = ny; y < height - 1; y++)
- {
- if (getPixel(hx - 1, y) == BLANK_COL)
- {
- setPixel(hx, y, BLANK_COL);
- floodFill(hx, y, MOUSE_COL);
- if (checkForFilledEdge() == 0) break;
- floodFill(hx, y, BLANK_COL);
- }
- }
- }
- if (y < height) mouth = true;
- }
- // Outline mouth / nose to protect and stop surrounding gfx 'bleeding' in.
- if (mouth) outlineArea(MOUSE_COL);
- if (nose) outlineArea(NOSE_COL);
- if (eyes) trimArea(EYES_COL, 3, 3); // Trim eyes to no more than 3 x 3
- if (nose && mouth) trimArea(NOSE_COL, 3, 3); // Trim nose to no more than 3 x 3. Mouth can be bigger..;
- mirror(); // Mirror to fix changes symmetrically.
- // Now search for any fill in any holes that doesn't leak to the edge of the sprite (passing over eyes, mouth and nose areas).
- const tmpCol:int = 4;
- for (y = 1; y < height -1; y++)
- {
- for (x = 1; x < hx - 1; x++)
- {
- if (getPixel(x, y) == BLANK_COL)
- {
- floodFill(x, y, tmpCol)
- floodFill(x, y, checkForFilledEdge() == 0 ? SOLID_COL : BLANK_COL);
- }
- }
- }
- mirror(); // Mirror finally (neccessary?)
- }
- public function mirror():void
- {
- var mtx:Matrix = new Matrix();
- mtx.scale(-1, 1);
- mtx.translate(width, 0);
- draw(this, mtx , null, null, new Rectangle(width/2, 0, width, height));
- }
- public function checkForFilledEdge():int
- {
- var c:int;
- for (var y:int = 0; y < height; y++)
- {
- c = getPixel(0, y);
- if (c != BLANK_COL && c != SOLID_COL) return 1;
- c = getPixel(width-1, y);
- if (c != BLANK_COL && c != SOLID_COL) return 1;
- }
- for (var x:int = 0; x < width; x++)
- {
- c = getPixel(x, 0);
- if (c != BLANK_COL && c != SOLID_COL) return 2;
- c = getPixel(x, height -1);
- if (c != BLANK_COL && c != SOLID_COL) return 2;
- }
- return 0;
- }
- public function outlineArea(col:int):void
- {
- for (var y:int = 0; y < height; y++)
- {
- for (var x:int = 0; x < width; x++)
- {
- var c:int = getPixel(x, y);
- if (c == col)
- {
- // diagonals are only outlined if blank (and not another reserved area).
- if (getPixel(x - 1, y - 1) == BLANK_COL) setPixel(x - 1, y - 1, SOLID_COL);
- if (getPixel(x , y - 1) != col) setPixel(x, y - 1, SOLID_COL);
- if (getPixel(x + 1, y - 1) == BLANK_COL) setPixel(x +1, y - 1, SOLID_COL);
- if (getPixel(x - 1, y) != col) setPixel(x - 1, y, SOLID_COL);
- if (getPixel(x + 1, y) != col) setPixel(x + 1, y, SOLID_COL);
- if (getPixel(x - 1, y + 1) == BLANK_COL) setPixel(x - 1, y + 1, SOLID_COL);
- if (getPixel(x, y + 1) != col) setPixel(x, y + 1, SOLID_COL);
- if (getPixel(x + 1, y + 1) == BLANK_COL) setPixel(x + 1, y + 1, SOLID_COL);
- }
- }
- }
- }
- public function trimArea(col:int, x2:int, y2:int ):void
- {
- var rx:int;
- var nx:int = -1;
- var ny:int = -1;
- for (var y:int = 0; y < height; y++)
- {
- for (var x:int = 0; x < width / 2; x++)
- {
- if (col == 1) rx = x;
- if (col > 1) rx = ((width / 2) - 1) - x;
- var c:int = getPixel(rx, y);
- if (c == col)
- {
- if (nx == -1) nx = x;
- if (ny == -1) ny = y;
- if (x >= nx + x2) setPixel(rx, y, SOLID_COL);
- if (y >= ny + y2) setPixel(rx, y, SOLID_COL);
- }
- }
- }
- }
- public function removeNoise(type:int):void
- {
- var noise:int = 4;
- var c:uint;
- for (var i:int = 0; i < noise; i++)
- {
- //Remove isolated pixels
- for (var y:int = 0; y < height; y++)
- {
- for (var x:int = 0; x < width; x++)
- {
- c = getPixel(x, y);
- if (c != BLANK_COL) continue;
- c = getPixel(x - 1, y - 1)
- + getPixel(x, y - 1)
- + getPixel(x + 1, y - 1)
- + getPixel(x - 1, y)
- + getPixel(x + 1, y)
- + getPixel(x - 1, y + 1)
- + getPixel(x, y + 1)
- + getPixel(x + 1, y + 1);
- if (type == 0 && c >= 8 * SOLID_COL)
- {
- setPixel(x, y, SOLID_COL);
- }
- if (type == 1 && c >= 7 * SOLID_COL)
- {
- setPixel(x, y, SOLID_COL);
- }
- // Join up 'one pixel' horizontal and vertical gaps, (adds a little order to the image).
- if (getPixel(x, y + 1) == SOLID_COL
- && getPixel(x, y -1 ) == SOLID_COL
- && getPixel(x-1, y ) != SOLID_COL
- && getPixel(x + 1, y ) != SOLID_COL
- && Crand.rand() % 5 > 2)
- {
- setPixel(x, y, SOLID_COL);
- }
- if (getPixel(x-1, y ) == SOLID_COL
- && getPixel(x + 1, y ) == SOLID_COL
- && getPixel(x, y + 1) != SOLID_COL
- && getPixel(x, y -1 ) != SOLID_COL
- && Crand.rand() % 5 > 2)
- {
- setPixel(x, y, SOLID_COL);
- }
- }
- }
- // Remove isolated pixels
- for (y = 0; y < height; y++)
- {
- for (x = 0; x < width; x++)
- {
- c = getPixel(x, y);
- if (c == 255)
- {
- // Add up surrounding pixels.
- c = getPixel(x, y - 1)
- + getPixel(x - 1, y)
- + getPixel(x - 1, y - 1)
- + getPixel(x + 1, y - 1)
- + getPixel(x + 1, y)
- + getPixel(x, y + 1)
- + getPixel(x - 1, y + 1)
- + getPixel(x + 1, y + 1);
- // No lit pixels around this one.
- if (c <= 0) setPixel(x, y, BLANK_COL);
- }
- }
- }
- }
- }
- }
- /*
- C rand()
- http://www001.upp.so-net.ne.jp/isaku/rand.html
- */
- class Crand
- {
- //Visual C++ version
- private static var x:int = 1;
- public static function rand():int
- {
- x = x * 214013 + 2531011;
- return (x>>16) & 32767;
- }
- public static function srand(s:int):void
- {
- x = s;
- }
- }
Retro Avatars forked from: Retro Avatars
- // forked from miyaoka's Retro Avatars
- /*
- =======================================
- Retro Avatars for Flash
- =======================================
- -Type avatar name to generate image.
- -press ENTER key to save current image as PNG.
- // Retro Avatars
- // -------------
- // By Richard Phipps
- // (Open source, but a credit if used would be nice!)
- http://retroremakes.com/forum/index.php/topic,657.0.html
- より移植してみました
- [Sample]
- http://www.indiegames.com/blog/2009/06/freeware_app_pick_retro_avatar.html
- http://www.flickr.com/photos/miyaoka/3592194889/
- */
- package
- {
- import flash.display.Sprite;
- import flash.text.TextField;
- import flash.text.TextFormat;
- import flash.text.TextFormatAlign;
- import flash.text.TextFieldType;
- import flash.text.TextFieldAutoSize;
- import flash.ui.Keyboard;
- import flash.events.KeyboardEvent;
- import flash.display.Bitmap;
- import flash.display.BitmapData;
- import flash.utils.ByteArray;
- import com.adobe.images.PNGEncoder;
- import flash.net.FileReference;
- import flash.geom.Matrix;
- import flash.system.Capabilities;
- import flash.system.IME;
- [SWF(width="465", height="465", backgroundColor= 0x0, frameRate="60")]
- public class RetroAvatars
- extends Sprite
- {
- private var tfd:TextField = new TextField();
- private var maxNameLength:uint = 9;
- private var bmd:AvatarBMD = new AvatarBMD(12, 12, false);
- private var bmd32:BitmapData = new BitmapData(bmd.width, bmd.height, true, 0x0);
- private var bmp:Bitmap = new Bitmap(bmd32);
- private static const EYES_COL:int = 0;
- private static const NOSE_COL:int = 0;
- private static const MOUSE_COL:int = 0;
- private var isFirst:Boolean = true;
- public function RetroAvatars():void
- {
- //bg
- graphics.beginFill(0);
- graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
- //ime off
- if (Capabilities.hasIME)
- {
- try
- {
- IME.enabled = false;
- }
- catch (e:Error) {}
- }
- //bmp
- bmp.scaleX = bmp.scaleY = 24;
- bmp.x = (stage.stageWidth - bmp.width) / 2;
- bmp.y = 40;
- addChild(bmp);
- //text
- var tft:TextFormat = new TextFormat();
- tft.align = TextFormatAlign.CENTER;
- tft.bold = true;
- tft.font = "Verdana";
- tft.letterSpacing = 5;
- tft.size = 48;
- tfd.defaultTextFormat = tft;
- tfd.autoSize = TextFieldAutoSize.CENTER;
- tfd.x = 465/2;
- tfd.y = 380;
- tfd.text = "ENTER NAME";
- tfd.textColor = 0xDDDDDD;
- isFirst = true;
- addChild(tfd);
- //event
- stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
- }
- private function keyDownHandler(e:KeyboardEvent):void
- {
- var cc:uint = e.charCode;
- // lower case keys, so make upper case.
- if (97 <= cc && cc <= 122) cc -= 32;
- if (isFirst) tfd.text = ""; isFirst = false;
- if (
- tfd.length < maxNameLength &&
- (
- cc == 32 // Space
- || (cc >= 65 && cc <= 90) //letters
- || (cc >= 48 && cc <= 57) //numbers
- )
- )
- {
- tfd.text = tfd.text.concat(String.fromCharCode(cc));
- }
- else if ( cc == 8 && tfd.length > 0) //Backspace
- {
- tfd.text = tfd.text.substr(0, tfd.length -1);
- }
- else if (cc == 13 && 0 < tfd.text.length) // ENTER key
- {
- //save PNG to local
- var mtx:Matrix = new Matrix();
- var sc:Number = 8;
- mtx.scale(sc, sc);
- var tempBmd:BitmapData = new BitmapData(bmd32.width * sc, bmd32.height * sc, true,0);
- tempBmd.draw(bmd32, mtx);
- var ba:ByteArray = PNGEncoder.encode(tempBmd);
- var fr:FileReference = new FileReference;
- fr.save(ba, tfd.text + ".png");
- }
- var nameLen:int = tfd.text.length;
- if (nameLen == 0)
- {
- bmd32.fillRect(bmd32.rect, 0);
- return;
- }
- // ------------
- // make code from text and set to srand
- Crand.srand(0);
- var code:int = 0;
- for (var g:int = 0; g < 32; g++)
- {
- code += tfd.text.charCodeAt(g % nameLen) * Crand.rand() % 1024;
- }
- Crand.srand(code); // Seed random generator with code.
- //make avatar color. Random (but not too dark) colour.
- var col:int =
- Crand.rand() % 192 + 64
- | Crand.rand() % 192 + 64 << 8
- | Crand.rand() % 192 + 64 << 16;
- tfd.textColor = col;
- // ------------
- // build avatar img
- bmd.build();
- bmd.removeNoise(0);
- bmd.mirror();
- bmd.enhanceFace();
- //copy to 32bit bmd and set color
- bmd32.threshold(bmd, bmd.rect, bmd.rect.topLeft, ">=", 0xff << 24 | AvatarBMD.SOLID_COL, 0xFF <<24 | col);
- bmd32.threshold(bmd, bmd.rect, bmd.rect.topLeft, "==", 0xff << 24 | AvatarBMD.EYES_COL, EYES_COL);
- bmd32.threshold(bmd, bmd.rect, bmd.rect.topLeft, "==", 0xff << 24 | AvatarBMD.NOSE_COL, NOSE_COL);
- bmd32.threshold(bmd, bmd.rect, bmd.rect.topLeft, "==", 0xff << 24 | AvatarBMD.MOUSE_COL, MOUSE_COL);
- bmd32.threshold(bmd, bmd.rect, bmd.rect.topLeft, "==", 0xff << 24 | AvatarBMD.BLANK_COL, 0);
- }
- }
- }
- import flash.display.BitmapData
- import flash.geom.Matrix;
- import flash.geom.Rectangle;
- class AvatarBMD
- extends BitmapData
- {
- public static const EYES_COL:int = 1;
- public static const NOSE_COL:int = 2;
- public static const MOUSE_COL:int = 3;
- public static const SOLID_COL:int = 0xFF;
- public static const BLANK_COL:int = 0x0;
- public function AvatarBMD(width:int, height:int, transparent:Boolean = true, fillColor:uint = 0xFFFFFFFF):void
- {
- //bmd24
- super(width, height, false, fillColor);
- }
- public function build():void
- {
- var c:int = 158;
- for (var y:int = 0; y < height; y++)
- {
- for (var x:int = 0; x < width; x++)
- {
- setPixel(x, y, (Crand.rand() % 356 > c) ? BLANK_COL : SOLID_COL);
- }
- }
- }
- public function enhanceFace():void
- {
- var eyes:Boolean;
- var nose:Boolean;
- var mouth:Boolean;
- var x:int;
- var y:int;
- var hx:int = width / 2 - 1; // Half width of sprite variable.
- // Detect eyes one pixel away from horizontal centre (look from just below the top edge to the middle of the vertical height).
- for (y = 1; y < height / 2; y++)
- {
- if (getPixel(hx - 1, y) == BLANK_COL) // 0 - Empty, Pixel?
- {
- floodFill(hx - 1, y, EYES_COL); // Mark area with reserved colour 1 (normal colours are 0 - empty & 255 - solid).
- if (checkForFilledEdge() == 0) break; // If this eye area doesn't touch the edges of the image, then stop searching.
- floodFill(hx - 1, y, BLANK_COL); // It reaches the edge, so refill as 0 - empty and keep looking.
- }
- if (getPixel(hx - 2, y) == BLANK_COL) // Any potential eye areas one pixel further away?
- {
- floodFill(hx - 2, y, EYES_COL);
- if (checkForFilledEdge() == 0) break;
- floodFill(hx - 2, y, BLANK_COL);
- }
- }
- // Ok, we didn't find anything!
- if ( y == height / 2)
- {
- // Try to make eyes from any centre pixels (converting them to one pixel further away. i.e. xx -> x x
- for ( y = 1; y < height; y++)
- {
- if (getPixel(hx - 1, y) == SOLID_COL && getPixel(hx, y) == BLANK_COL)
- {
- setPixel(hx - 1, y, BLANK_COL);
- setPixel(hx, y, SOLID_COL);
- setPixel(hx - 1, y + 1, BLANK_COL); // Make the eye 2 pixels (at least) high.
- floodFill(hx - 1, y, EYES_COL);
- if (checkForFilledEdge() == 0) break;
- floodFill(hx - 1, y, BLANK_COL);
- }
- }
- }
- var ny:int = y + 1;
- if (y < height) eyes = true; // Ok, we did find eyes
- // Still NO eyes.
- if (!eyes)
- {
- // Ok, create fake eyes!
- y = 1 + Crand.rand() % (height / 2);
- setPixel(hx - 1, y, EYES_COL);
- outlineArea(1); // Outline to protect area.
- eyes = true;
- ny = y + 1;
- }
- // Remove any joined up eyes (i.e xx instead of x x)
- for (y = 1; y < height; y++)
- {
- if (getPixel(hx, y) == EYES_COL)
- {
- setPixel(hx, y, SOLID_COL);
- setPixel(hx - 1, y, EYES_COL);
- }
- else
- {
- if (getPixel(hx - 2, y) == EYES_COL) setPixel(hx, y, SOLID_COL);
- if (getPixel(hx - 1, y) == EYES_COL) setPixel(hx, y, SOLID_COL);
- }
- }
- mirror(); // Miror all eye work.
- if (eyes) outlineArea(EYES_COL); // Protect eyes with solid outline.
- trace(ny);
- // -------
- // Detect nose
- for (y = ny; y < height; y++)
- {
- if (getPixel(hx, y) == BLANK_COL)
- {
- floodFill(hx, y, NOSE_COL); // Fill with area colour 2.
- if ( checkForFilledEdge() == 0) break;
- floodFill(hx, y, BLANK_COL);
- }
- }
- if ( y < 10) nose = true;
- // No nose?
- if (!nose)
- {
- // Ok, we won't find a mouth either, but we need to make a nose/mouth one out of any open sections (regardless of touching the edge)
- for (y = ny; y < height - 1; y++)
- {
- if (getPixel(hx, y) == BLANK_COL)
- {
- setPixel(hx, y, NOSE_COL)
- nose = true;
- break;
- }
- }
- // Try to find a nose/mouth one pixel away which we can join up. i.e. x x -> xxxx
- if (!nose)
- {
- for (y = ny; y < height - 1; y++)
- {
- if (getPixel(hx - 1, y) == BLANK_COL)
- {
- setPixel(hx -1, y, NOSE_COL)
- setPixel(hx, y, NOSE_COL)
- nose = true;
- break;
- }
- }
- // Ok, NOTHING, just create fake mouth/nose!
- if (!nose)
- {
- y = ny + 1 + Crand.rand() % (height / 3);
- if (y > height - 2) y = height - 2;
- setPixel(hx, y, NOSE_COL)
- nose = true;
- ny = y + 1;
- }
- }
- }
- else
- {
- ny = y + 1;
- // --------
- // Detect mouth
- for (y = ny; y < height; y++)
- {
- if (getPixel(hx, y) == BLANK_COL)
- {
- floodFill(hx, y, MOUSE_COL);
- if (checkForFilledEdge() == 0) break;
- floodFill(hx, y, BLANK_COL);
- }
- }
- if (y < height) mouth = true;
- if (!mouth) // Still no mouse, so look one pixel further away and then if found, join up.
- {
- for (y = ny; y < height - 1; y++)
- {
- if (getPixel(hx - 1, y) == BLANK_COL)
- {
- setPixel(hx, y, BLANK_COL);
- floodFill(hx, y, MOUSE_COL);
- if (checkForFilledEdge() == 0) break;
- floodFill(hx, y, BLANK_COL);
- }
- }
- }
- if (y < height) mouth = true;
- }
- // Outline mouth / nose to protect and stop surrounding gfx 'bleeding' in.
- if (mouth) outlineArea(MOUSE_COL);
- if (nose) outlineArea(NOSE_COL);
- if (eyes) trimArea(EYES_COL, 3, 3); // Trim eyes to no more than 3 x 3
- if (nose && mouth) trimArea(NOSE_COL, 3, 3); // Trim nose to no more than 3 x 3. Mouth can be bigger..;
- mirror(); // Mirror to fix changes symmetrically.
- // Now search for any fill in any holes that doesn't leak to the edge of the sprite (passing over eyes, mouth and nose areas).
- const tmpCol:int = 4;
- for (y = 1; y < height -1; y++)
- {
- for (x = 1; x < hx - 1; x++)
- {
- if (getPixel(x, y) == BLANK_COL)
- {
- floodFill(x, y, tmpCol)
- floodFill(x, y, checkForFilledEdge() == 0 ? SOLID_COL : BLANK_COL);
- }
- }
- }
- mirror(); // Mirror finally (neccessary?)
- }
- public function mirror():void
- {
- var mtx:Matrix = new Matrix();
- mtx.scale(-1, 1);
- mtx.translate(width, 0);
- draw(this, mtx , null, null, new Rectangle(width/2, 0, width, height));
- }
- public function checkForFilledEdge():int
- {
- var c:int;
- for (var y:int = 0; y < height; y++)
- {
- c = getPixel(0, y);
- if (c != BLANK_COL && c != SOLID_COL) return 1;
- c = getPixel(width-1, y);
- if (c != BLANK_COL && c != SOLID_COL) return 1;
- }
- for (var x:int = 0; x < width; x++)
- {
- c = getPixel(x, 0);
- if (c != BLANK_COL && c != SOLID_COL) return 2;
- c = getPixel(x, height -1);
- if (c != BLANK_COL && c != SOLID_COL) return 2;
- }
- return 0;
- }
- public function outlineArea(col:int):void
- {
- for (var y:int = 0; y < height; y++)
- {
- for (var x:int = 0; x < width; x++)
- {
- var c:int = getPixel(x, y);
- if (c == col)
- {
- // diagonals are only outlined if blank (and not another reserved area).
- if (getPixel(x - 1, y - 1) == BLANK_COL) setPixel(x - 1, y - 1, SOLID_COL);
- if (getPixel(x , y - 1) != col) setPixel(x, y - 1, SOLID_COL);
- if (getPixel(x + 1, y - 1) == BLANK_COL) setPixel(x +1, y - 1, SOLID_COL);
- if (getPixel(x - 1, y) != col) setPixel(x - 1, y, SOLID_COL);
- if (getPixel(x + 1, y) != col) setPixel(x + 1, y, SOLID_COL);
- if (getPixel(x - 1, y + 1) == BLANK_COL) setPixel(x - 1, y + 1, SOLID_COL);
- if (getPixel(x, y + 1) != col) setPixel(x, y + 1, SOLID_COL);
- if (getPixel(x + 1, y + 1) == BLANK_COL) setPixel(x + 1, y + 1, SOLID_COL);
- }
- }
- }
- }
- public function trimArea(col:int, x2:int, y2:int ):void
- {
- var rx:int;
- var nx:int = -1;
- var ny:int = -1;
- for (var y:int = 0; y < height; y++)
- {
- for (var x:int = 0; x < width / 2; x++)
- {
- if (col == 1) rx = x;
- if (col > 1) rx = ((width / 2) - 1) - x;
- var c:int = getPixel(rx, y);
- if (c == col)
- {
- if (nx == -1) nx = x;
- if (ny == -1) ny = y;
- if (x >= nx + x2) setPixel(rx, y, SOLID_COL);
- if (y >= ny + y2) setPixel(rx, y, SOLID_COL);
- }
- }
- }
- }
- public function removeNoise(type:int):void
- {
- var noise:int = 4;
- var c:uint;
- for (var i:int = 0; i < noise; i++)
- {
- //Remove isolated pixels
- for (var y:int = 0; y < height; y++)
- {
- for (var x:int = 0; x < width; x++)
- {
- c = getPixel(x, y);
- if (c != BLANK_COL) continue;
- c = getPixel(x - 1, y - 1)
- + getPixel(x, y - 1)
- + getPixel(x + 1, y - 1)
- + getPixel(x - 1, y)
- + getPixel(x + 1, y)
- + getPixel(x - 1, y + 1)
- + getPixel(x, y + 1)
- + getPixel(x + 1, y + 1);
- if (type == 0 && c >= 8 * SOLID_COL)
- {
- setPixel(x, y, SOLID_COL);
- }
- if (type == 1 && c >= 7 * SOLID_COL)
- {
- setPixel(x, y, SOLID_COL);
- }
- // Join up 'one pixel' horizontal and vertical gaps, (adds a little order to the image).
- if (getPixel(x, y + 1) == SOLID_COL
- && getPixel(x, y -1 ) == SOLID_COL
- && getPixel(x-1, y ) != SOLID_COL
- && getPixel(x + 1, y ) != SOLID_COL
- && Crand.rand() % 5 > 2)
- {
- setPixel(x, y, SOLID_COL);
- }
- if (getPixel(x-1, y ) == SOLID_COL
- && getPixel(x + 1, y ) == SOLID_COL
- && getPixel(x, y + 1) != SOLID_COL
- && getPixel(x, y -1 ) != SOLID_COL
- && Crand.rand() % 5 > 2)
- {
- setPixel(x, y, SOLID_COL);
- }
- }
- }
- // Remove isolated pixels
- for (y = 0; y < height; y++)
- {
- for (x = 0; x < width; x++)
- {
- c = getPixel(x, y);
- if (c == 255)
- {
- // Add up surrounding pixels.
- c = getPixel(x, y - 1)
- + getPixel(x - 1, y)
- + getPixel(x - 1, y - 1)
- + getPixel(x + 1, y - 1)
- + getPixel(x + 1, y)
- + getPixel(x, y + 1)
- + getPixel(x - 1, y + 1)
- + getPixel(x + 1, y + 1);
- // No lit pixels around this one.
- if (c <= 0) setPixel(x, y, BLANK_COL);
- }
- }
- }
- }
- }
- }
- /*
- C rand()
- http://www001.upp.so-net.ne.jp/isaku/rand.html
- */
- class Crand
- {
- //Visual C++ version
- private static var x:int = 1;
- public static function rand():int
- {
- x = x * 214013 + 2531011;
- return (x>>16) & 32767;
- }
- public static function srand(s:int):void
- {
- x = s;
- }
- }
Retro Avatars forked from: Retro Avatars
- // forked from miyaoka's Retro Avatars
- /*
- =======================================
- Retro Avatars for Flash
- =======================================
- -Type avatar name to generate image.
- -press ENTER key to save current image as PNG.
- // Retro Avatars
- // -------------
- // By Richard Phipps
- // (Open source, but a credit if used would be nice!)
- http://retroremakes.com/forum/index.php/topic,657.0.html
- より移植してみました
- [Sample]
- http://www.indiegames.com/blog/2009/06/freeware_app_pick_retro_avatar.html
- http://www.flickr.com/photos/miyaoka/3592194889/
- */
- package
- {
- import flash.display.Sprite;
- import flash.text.TextField;
- import flash.text.TextFormat;
- import flash.text.TextFormatAlign;
- import flash.text.TextFieldType;
- import flash.text.TextFieldAutoSize;
- import flash.ui.Keyboard;
- import flash.events.KeyboardEvent;
- import flash.display.Bitmap;
- import flash.display.BitmapData;
- import flash.utils.ByteArray;
- import com.adobe.images.PNGEncoder;
- import flash.net.FileReference;
- import flash.geom.Matrix;
- import flash.system.Capabilities;
- import flash.system.IME;
- [SWF(width="465", height="465", backgroundColor= 0x0, frameRate="60")]
- public class RetroAvatars
- extends Sprite
- {
- private var tfd:TextField = new TextField();
- private var maxNameLength:uint = 9;
- private var bmd:AvatarBMD = new AvatarBMD(12, 12, false);
- private var bmd32:BitmapData = new BitmapData(bmd.width, bmd.height, true, 0x0);
- private var bmp:Bitmap = new Bitmap(bmd32);
- private static const EYES_COL:int = 0;
- private static const NOSE_COL:int = 0;
- private static const MOUSE_COL:int = 0;
- private var isFirst:Boolean = true;
- public function RetroAvatars():void
- {
- //bg
- graphics.beginFill(0);
- graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
- //ime off
- if (Capabilities.hasIME)
- {
- try
- {
- IME.enabled = false;
- }
- catch (e:Error) {}
- }
- //bmp
- bmp.scaleX = bmp.scaleY = 24;
- bmp.x = (stage.stageWidth - bmp.width) / 2;
- bmp.y = 40;
- addChild(bmp);
- //text
- var tft:TextFormat = new TextFormat();
- tft.align = TextFormatAlign.CENTER;
- tft.bold = true;
- tft.font = "Verdana";
- tft.letterSpacing = 5;
- tft.size = 48;
- tfd.defaultTextFormat = tft;
- tfd.autoSize = TextFieldAutoSize.CENTER;
- tfd.x = 465/2;
- tfd.y = 380;
- tfd.text = "ENTER NAME";
- tfd.textColor = 0xDDDDDD;
- isFirst = true;
- addChild(tfd);
- //event
- stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
- }
- private function keyDownHandler(e:KeyboardEvent):void
- {
- var cc:uint = e.charCode;
- // lower case keys, so make upper case.
- if (97 <= cc && cc <= 122) cc -= 32;
- if (isFirst) tfd.text = ""; isFirst = false;
- if (
- tfd.length < maxNameLength &&
- (
- cc == 32 // Space
- || (cc >= 65 && cc <= 90) //letters
- || (cc >= 48 && cc <= 57) //numbers
- )
- )
- {
- tfd.text = tfd.text.concat(String.fromCharCode(cc));
- }
- else if ( cc == 8 && tfd.length > 0) //Backspace
- {
- tfd.text = tfd.text.substr(0, tfd.length -1);
- }
- else if (cc == 13 && 0 < tfd.text.length) // ENTER key
- {
- //save PNG to local
- var mtx:Matrix = new Matrix();
- var sc:Number = 8;
- mtx.scale(sc, sc);
- var tempBmd:BitmapData = new BitmapData(bmd32.width * sc, bmd32.height * sc, true,0);
- tempBmd.draw(bmd32, mtx);
- var ba:ByteArray = PNGEncoder.encode(tempBmd);
- var fr:FileReference = new FileReference;
- fr.save(ba, tfd.text + ".png");
- }
- var nameLen:int = tfd.text.length;
- if (nameLen == 0)
- {
- bmd32.fillRect(bmd32.rect, 0);
- return;
- }
- // ------------
- // make code from text and set to srand
- Crand.srand(0);
- var code:int = 0;
- for (var g:int = 0; g < 32; g++)
- {
- code += tfd.text.charCodeAt(g % nameLen) * Crand.rand() % 1024;
- }
- Crand.srand(code); // Seed random generator with code.
- //make avatar color. Random (but not too dark) colour.
- var col:int =
- Crand.rand() % 192 + 64
- | Crand.rand() % 192 + 64 << 8
- | Crand.rand() % 192 + 64 << 16;
- tfd.textColor = col;
- // ------------
- // build avatar img
- bmd.build();
- bmd.removeNoise(0);
- bmd.mirror();
- bmd.enhanceFace();
- //copy to 32bit bmd and set color
- bmd32.threshold(bmd, bmd.rect, bmd.rect.topLeft, ">=", 0xff << 24 | AvatarBMD.SOLID_COL, 0xFF <<24 | col);
- bmd32.threshold(bmd, bmd.rect, bmd.rect.topLeft, "==", 0xff << 24 | AvatarBMD.EYES_COL, EYES_COL);
- bmd32.threshold(bmd, bmd.rect, bmd.rect.topLeft, "==", 0xff << 24 | AvatarBMD.NOSE_COL, NOSE_COL);
- bmd32.threshold(bmd, bmd.rect, bmd.rect.topLeft, "==", 0xff << 24 | AvatarBMD.MOUSE_COL, MOUSE_COL);
- bmd32.threshold(bmd, bmd.rect, bmd.rect.topLeft, "==", 0xff << 24 | AvatarBMD.BLANK_COL, 0);
- }
- }
- }
- import flash.display.BitmapData
- import flash.geom.Matrix;
- import flash.geom.Rectangle;
- class AvatarBMD
- extends BitmapData
- {
- public static const EYES_COL:int = 1;
- public static const NOSE_COL:int = 2;
- public static const MOUSE_COL:int = 3;
- public static const SOLID_COL:int = 0xFF;
- public static const BLANK_COL:int = 0x0;
- public function AvatarBMD(width:int, height:int, transparent:Boolean = true, fillColor:uint = 0xFFFFFFFF):void
- {
- //bmd24
- super(width, height, false, fillColor);
- }
- public function build():void
- {
- var c:int = 158;
- for (var y:int = 0; y < height; y++)
- {
- for (var x:int = 0; x < width; x++)
- {
- setPixel(x, y, (Crand.rand() % 356 > c) ? BLANK_COL : SOLID_COL);
- }
- }
- }
- public function enhanceFace():void
- {
- var eyes:Boolean;
- var nose:Boolean;
- var mouth:Boolean;
- var x:int;
- var y:int;
- var hx:int = width / 2 - 1; // Half width of sprite variable.
- // Detect eyes one pixel away from horizontal centre (look from just below the top edge to the middle of the vertical height).
- for (y = 1; y < height / 2; y++)
- {
- if (getPixel(hx - 1, y) == BLANK_COL) // 0 - Empty, Pixel?
- {
- floodFill(hx - 1, y, EYES_COL); // Mark area with reserved colour 1 (normal colours are 0 - empty & 255 - solid).
- if (checkForFilledEdge() == 0) break; // If this eye area doesn't touch the edges of the image, then stop searching.
- floodFill(hx - 1, y, BLANK_COL); // It reaches the edge, so refill as 0 - empty and keep looking.
- }
- if (getPixel(hx - 2, y) == BLANK_COL) // Any potential eye areas one pixel further away?
- {
- floodFill(hx - 2, y, EYES_COL);
- if (checkForFilledEdge() == 0) break;
- floodFill(hx - 2, y, BLANK_COL);
- }
- }
- // Ok, we didn't find anything!
- if ( y == height / 2)
- {
- // Try to make eyes from any centre pixels (converting them to one pixel further away. i.e. xx -> x x
- for ( y = 1; y < height; y++)
- {
- if (getPixel(hx - 1, y) == SOLID_COL && getPixel(hx, y) == BLANK_COL)
- {
- setPixel(hx - 1, y, BLANK_COL);
- setPixel(hx, y, SOLID_COL);
- setPixel(hx - 1, y + 1, BLANK_COL); // Make the eye 2 pixels (at least) high.
- floodFill(hx - 1, y, EYES_COL);
- if (checkForFilledEdge() == 0) break;
- floodFill(hx - 1, y, BLANK_COL);
- }
- }
- }
- var ny:int = y + 1;
- if (y < height) eyes = true; // Ok, we did find eyes
- // Still NO eyes.
- if (!eyes)
- {
- // Ok, create fake eyes!
- y = 1 + Crand.rand() % (height / 2);
- setPixel(hx - 1, y, EYES_COL);
- outlineArea(1); // Outline to protect area.
- eyes = true;
- ny = y + 1;
- }
- // Remove any joined up eyes (i.e xx instead of x x)
- for (y = 1; y < height; y++)
- {
- if (getPixel(hx, y) == EYES_COL)
- {
- setPixel(hx, y, SOLID_COL);
- setPixel(hx - 1, y, EYES_COL);
- }
- else
- {
- if (getPixel(hx - 2, y) == EYES_COL) setPixel(hx, y, SOLID_COL);
- if (getPixel(hx - 1, y) == EYES_COL) setPixel(hx, y, SOLID_COL);
- }
- }
- mirror(); // Miror all eye work.
- if (eyes) outlineArea(EYES_COL); // Protect eyes with solid outline.
- trace(ny);
- // -------
- // Detect nose
- for (y = ny; y < height; y++)
- {
- if (getPixel(hx, y) == BLANK_COL)
- {
- floodFill(hx, y, NOSE_COL); // Fill with area colour 2.
- if ( checkForFilledEdge() == 0) break;
- floodFill(hx, y, BLANK_COL);
- }
- }
- if ( y < 10) nose = true;
- // No nose?
- if (!nose)
- {
- // Ok, we won't find a mouth either, but we need to make a nose/mouth one out of any open sections (regardless of touching the edge)
- for (y = ny; y < height - 1; y++)
- {
- if (getPixel(hx, y) == BLANK_COL)
- {
- setPixel(hx, y, NOSE_COL)
- nose = true;
- break;
- }
- }
- // Try to find a nose/mouth one pixel away which we can join up. i.e. x x -> xxxx
- if (!nose)
- {
- for (y = ny; y < height - 1; y++)
- {
- if (getPixel(hx - 1, y) == BLANK_COL)
- {
- setPixel(hx -1, y, NOSE_COL)
- setPixel(hx, y, NOSE_COL)
- nose = true;
- break;
- }
- }
- // Ok, NOTHING, just create fake mouth/nose!
- if (!nose)
- {
- y = ny + 1 + Crand.rand() % (height / 3);
- if (y > height - 2) y = height - 2;
- setPixel(hx, y, NOSE_COL)
- nose = true;
- ny = y + 1;
- }
- }
- }
- else
- {
- ny = y + 1;
- // --------
- // Detect mouth
- for (y = ny; y < height; y++)
- {
- if (getPixel(hx, y) == BLANK_COL)
- {
- floodFill(hx, y, MOUSE_COL);
- if (checkForFilledEdge() == 0) break;
- floodFill(hx, y, BLANK_COL);
- }
- }
- if (y < height) mouth = true;
- if (!mouth) // Still no mouse, so look one pixel further away and then if found, join up.
- {
- for (y = ny; y < height - 1; y++)
- {
- if (getPixel(hx - 1, y) == BLANK_COL)
- {
- setPixel(hx, y, BLANK_COL);
- floodFill(hx, y, MOUSE_COL);
- if (checkForFilledEdge() == 0) break;
- floodFill(hx, y, BLANK_COL);
- }
- }
- }
- if (y < height) mouth = true;
- }
- // Outline mouth / nose to protect and stop surrounding gfx 'bleeding' in.
- if (mouth) outlineArea(MOUSE_COL);
- if (nose) outlineArea(NOSE_COL);
- if (eyes) trimArea(EYES_COL, 3, 3); // Trim eyes to no more than 3 x 3
- if (nose && mouth) trimArea(NOSE_COL, 3, 3); // Trim nose to no more than 3 x 3. Mouth can be bigger..;
- mirror(); // Mirror to fix changes symmetrically.
- // Now search for any fill in any holes that doesn't leak to the edge of the sprite (passing over eyes, mouth and nose areas).
- const tmpCol:int = 4;
- for (y = 1; y < height -1; y++)
- {
- for (x = 1; x < hx - 1; x++)
- {
- if (getPixel(x, y) == BLANK_COL)
- {
- floodFill(x, y, tmpCol)
- floodFill(x, y, checkForFilledEdge() == 0 ? SOLID_COL : BLANK_COL);
- }
- }
- }
- mirror(); // Mirror finally (neccessary?)
- }
- public function mirror():void
- {
- var mtx:Matrix = new Matrix();
- mtx.scale(-1, 1);
- mtx.translate(width, 0);
- draw(this, mtx , null, null, new Rectangle(width/2, 0, width, height));
- }
- public function checkForFilledEdge():int
- {
- var c:int;
- for (var y:int = 0; y < height; y++)
- {
- c = getPixel(0, y);
- if (c != BLANK_COL && c != SOLID_COL) return 1;
- c = getPixel(width-1, y);
- if (c != BLANK_COL && c != SOLID_COL) return 1;
- }
- for (var x:int = 0; x < width; x++)
- {
- c = getPixel(x, 0);
- if (c != BLANK_COL && c != SOLID_COL) return 2;
- c = getPixel(x, height -1);
- if (c != BLANK_COL && c != SOLID_COL) return 2;
- }
- return 0;
- }
- public function outlineArea(col:int):void
- {
- for (var y:int = 0; y < height; y++)
- {
- for (var x:int = 0; x < width; x++)
- {
- var c:int = getPixel(x, y);
- if (c == col)
- {
- // diagonals are only outlined if blank (and not another reserved area).
- if (getPixel(x - 1, y - 1) == BLANK_COL) setPixel(x - 1, y - 1, SOLID_COL);
- if (getPixel(x , y - 1) != col) setPixel(x, y - 1, SOLID_COL);
- if (getPixel(x + 1, y - 1) == BLANK_COL) setPixel(x +1, y - 1, SOLID_COL);
- if (getPixel(x - 1, y) != col) setPixel(x - 1, y, SOLID_COL);
- if (getPixel(x + 1, y) != col) setPixel(x + 1, y, SOLID_COL);
- if (getPixel(x - 1, y + 1) == BLANK_COL) setPixel(x - 1, y + 1, SOLID_COL);
- if (getPixel(x, y + 1) != col) setPixel(x, y + 1, SOLID_COL);
- if (getPixel(x + 1, y + 1) == BLANK_COL) setPixel(x + 1, y + 1, SOLID_COL);
- }
- }
- }
- }
- public function trimArea(col:int, x2:int, y2:int ):void
- {
- var rx:int;
- var nx:int = -1;
- var ny:int = -1;
- for (var y:int = 0; y < height; y++)
- {
- for (var x:int = 0; x < width / 2; x++)
- {
- if (col == 1) rx = x;
- if (col > 1) rx = ((width / 2) - 1) - x;
- var c:int = getPixel(rx, y);
- if (c == col)
- {
- if (nx == -1) nx = x;
- if (ny == -1) ny = y;
- if (x >= nx + x2) setPixel(rx, y, SOLID_COL);
- if (y >= ny + y2) setPixel(rx, y, SOLID_COL);
- }
- }
- }
- }
- public function removeNoise(type:int):void
- {
- var noise:int = 4;
- var c:uint;
- for (var i:int = 0; i < noise; i++)
- {
- //Remove isolated pixels
- for (var y:int = 0; y < height; y++)
- {
- for (var x:int = 0; x < width; x++)
- {
- c = getPixel(x, y);
- if (c != BLANK_COL) continue;
- c = getPixel(x - 1, y - 1)
- + getPixel(x, y - 1)
- + getPixel(x + 1, y - 1)
- + getPixel(x - 1, y)
- + getPixel(x + 1, y)
- + getPixel(x - 1, y + 1)
- + getPixel(x, y + 1)
- + getPixel(x + 1, y + 1);
- if (type == 0 && c >= 8 * SOLID_COL)
- {
- setPixel(x, y, SOLID_COL);
- }
- if (type == 1 && c >= 7 * SOLID_COL)
- {
- setPixel(x, y, SOLID_COL);
- }
- // Join up 'one pixel' horizontal and vertical gaps, (adds a little order to the image).
- if (getPixel(x, y + 1) == SOLID_COL
- && getPixel(x, y -1 ) == SOLID_COL
- && getPixel(x-1, y ) != SOLID_COL
- && getPixel(x + 1, y ) != SOLID_COL
- && Crand.rand() % 5 > 2)
- {
- setPixel(x, y, SOLID_COL);
- }
- if (getPixel(x-1, y ) == SOLID_COL
- && getPixel(x + 1, y ) == SOLID_COL
- && getPixel(x, y + 1) != SOLID_COL
- && getPixel(x, y -1 ) != SOLID_COL
- && Crand.rand() % 5 > 2)
- {
- setPixel(x, y, SOLID_COL);
- }
- }
- }
- // Remove isolated pixels
- for (y = 0; y < height; y++)
- {
- for (x = 0; x < width; x++)
- {
- c = getPixel(x, y);
- if (c == 255)
- {
- // Add up surrounding pixels.
- c = getPixel(x, y - 1)
- + getPixel(x - 1, y)
- + getPixel(x - 1, y - 1)
- + getPixel(x + 1, y - 1)
- + getPixel(x + 1, y)
- + getPixel(x, y + 1)
- + getPixel(x - 1, y + 1)
- + getPixel(x + 1, y + 1);
- // No lit pixels around this one.
- if (c <= 0) setPixel(x, y, BLANK_COL);
- }
- }
- }
- }
- }
- }
- /*
- C rand()
- http://www001.upp.so-net.ne.jp/isaku/rand.html
- */
- class Crand
- {
- //Visual C++ version
- private static var x:int = 1;
- public static function rand():int
- {
- x = x * 214013 + 2531011;
- return (x>>16) & 32767;
- }
- public static function srand(s:int):void
- {
- x = s;
- }
- }
notice:




