Показать сообщение отдельно
Старый 27.02.2014, 15:28
silin вне форума Посмотреть профиль Посетить домашнюю страницу silin Найти все сообщения от silin
  № 9  
Ответить с цитированием
silin
 
Аватар для silin

блогер
Регистрация: Mar 2003
Адрес: Моск. обл.
Сообщений: 5,269
Записей в блоге: 6
а вот та же задачка, но для картинок с пересекающимися ректанглами
как бы еще более бессмысленное дело в контексте спрайтшитов, но пусть тоже будет раз уж
Код AS3:
package
{
	import flash.display.*;
	import flash.geom.*;
 
	public class Main extends Sprite
	{
		[Embed(source="test.png")]
		public static const test_png:Class;
 
		public function Main():void
		{
 
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
 
			var bmd:BitmapData = Bitmap(new test_png()).bitmapData;
			addChild(new Bitmap(bmd));
 
 
			//разбиваем
			var arr:Array = splitBitmapByAlpha(bmd);
 
			// смотрим
			var tX:Number = bmd.width + 10;
			graphics.lineStyle(0, 0xC0C0C0);
			for (var i:int = 0; i < arr.length; i++)
			{
				var fragm:Bitmap = new Bitmap(arr[i]);
				addChild(fragm);
				fragm.x = tX;
				fragm.y = 10;
 
				tX += fragm.width + 10;
				graphics.drawRect(fragm.x, fragm.y, fragm.width, fragm.height);
			}
 
		}
 
		public static function splitBitmapByAlpha(bmd:BitmapData):Array /*BitmapData*/
		{
 
			var res:Array = [];
			var w:int = bmd.width;
			var h:int = bmd.height;
			var k:int = 0;
			var p0:Point = new Point();
 
			// карта непрозрачности
			var map:BitmapData = bmd.clone();
			map.threshold(map, map.rect, p0, ">", 0, 0xFF000000, 0xFF000000);
 
 
			// пока битмап не пустой
			while (map.getColorBoundsRect(0xFF000000, 0x0, false).width)
			{
				// ищем следующую непрозрачную точку
				while (!map.getPixel32(k % w, k / w)) k++;
 
				// заливаем красным
				map.floodFill(k % w, k / w, 0xFFFF0000);
				// берем что залилось как маску
				var mask:BitmapData = new BitmapData(w, h, true, 0x0);
				mask.copyChannel(map, map.rect, p0, BitmapDataChannel.RED, BitmapDataChannel.ALPHA);
				// фрагмент
				var fragmRect:Rectangle = mask.getColorBoundsRect(0xFF000000, 0x0, false);
				var fragmBmd:BitmapData = new BitmapData(fragmRect.width, fragmRect.height, true, 0x0);
				// вынимаем  по маске из основного
				fragmBmd.copyPixels(bmd, fragmRect, p0, mask , fragmRect.topLeft);
				// удаляем  отработанный кусок
				map.threshold(mask, mask.rect, p0, "==", 0xFF000000, 0x0, 0xFF000000);
				mask.dispose();
				res.push(fragmBmd);
 
			}
 
			map.dispose();
			return res;
		}
 
	}
 
}
upd. небольшая оптимизация (нет нужды искать на каждой итерации по всей карте, а можно продолжать от предыдущей)
alphaSplit.swf   (29.9 Кб)
Вложения
Тип файла: swf alphaSplit.swf (29.9 Кб, 199 просмотров)


Последний раз редактировалось silin; 27.02.2014 в 21:41.