Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 30.05.2015, 16:59
AlexCooper вне форума Посмотреть профиль Отправить личное сообщение для AlexCooper Найти все сообщения от AlexCooper
  № 21  
Ответить с цитированием
AlexCooper
 
Аватар для AlexCooper

Регистрация: Sep 2008
Адрес: Черкассы
Сообщений: 1,167
Записей в блоге: 1
Отправить сообщение для AlexCooper с помощью ICQ Отправить сообщение для AlexCooper с помощью Skype™
Цитата:
Сообщение от Alex626 Посмотреть сообщение
Но вообще, интересно, как можно разбить на блоки. AlexCooper, расскажите, пожалуйста, больше.
Так быстро и не расскажешь. Лучше пример посмотреть, сейчас быстренько соберу чёнить
__________________
return this...

Старый 30.05.2015, 19:14
AlexCooper вне форума Посмотреть профиль Отправить личное сообщение для AlexCooper Найти все сообщения от AlexCooper
  № 22  
Ответить с цитированием
AlexCooper
 
Аватар для AlexCooper

Регистрация: Sep 2008
Адрес: Черкассы
Сообщений: 1,167
Записей в блоге: 1
Отправить сообщение для AlexCooper с помощью ICQ Отправить сообщение для AlexCooper с помощью Skype™
FB4.7 SectorBuilder.rar

Main.as
Код AS3:
package
{
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.JPEGEncoderOptions;
	import flash.display.Sprite;
 
	import flash.net.FileReference;
	import flash.utils.ByteArray;
 
	import utils.SeparateBuilder;
	import utils.SeparateEvent;
 
	import view.RandomView;
 
	[SWF(width="960",height="640",frameRate="60",backgroundColor="#FFFFFF")]
	public class Main extends Sprite
	{
		private var _viewport:Sprite;
		private var rview:DisplayObject
		private var _separe:SeparateBuilder;
 
 
		public function Main()
		{
			_viewport = new Sprite();
			addChild( _viewport );
 
			createRandomView();
			adaptViewPort();
			createSeparator();
			createScreenshot();
		}
 
		private function adaptViewPort():void
		{
			_viewport.width = stage.stageWidth;
			_viewport.height =  stage.stageHeight;
		}
 
		private function createRandomView():void
		{
			rview = new RandomView(5000,5000);
 
			_viewport.addChild( rview );
		}
 
		private function createSeparator():void {
 
			_separe = new SeparateBuilder(500);
 
			_separe.addEventListener( SeparateEvent.INIT, 	separateHandler );
			_separe.addEventListener( SeparateEvent.COMPLETE, 	separateHandler );
			_separe.addEventListener( SeparateEvent.PROCESSING, separateHandler );
 
		}
 
		private function createScreenshot():void {
			_separe.work( rview ); 			
		}
 
		protected function separateHandler(event:SeparateEvent):void
		{
			switch (event.type) {
 
				case SeparateEvent.INIT:
 
					trace('Start');
					break;
 
				case SeparateEvent.PROCESSING :
					trace('Processing : '+ event.data);
					break;
 
				case SeparateEvent.COMPLETE :
 
					trace('Complete');
 
					encode( _separe.bitmapData );
 
					break;
			}
		}
 
		private function encode(bitmapData:BitmapData):void
		{
			var jpeg:JPEGEncoderOptions = new JPEGEncoderOptions();
				jpeg.quality = 4;
 
			var byteArray:ByteArray = bitmapData.encode( bitmapData.rect, jpeg);
 
			save( byteArray );
		}
 
		private function save(byteArray:ByteArray):void
		{
			var fr:FileReference = new FileReference();
				fr.save(
					byteArray ,
					'screenshot_'+new Date().time+'.jpg'
				);
		}
	}
}
utils.SeparateBuilder.as
Код AS3:
package utils
{
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.events.EventDispatcher;
	import flash.geom.Point;
	import flash.utils.ByteArray;
	import flash.utils.setTimeout;
 
	import net.alexscript.hack.Extruder;
 
	public class SeparateBuilder extends EventDispatcher
	{
		private var _blockSize:Number;
		private var _height:Number;
 
		private var _target:DisplayObject;
 
		private var _byteArray:ByteArray;
		private var _map:Point;
		private var _iteration:uint;
		private var _cache:BitmapData;
 
		public function SeparateBuilder(blockSize:Number=500)
		{
			super();
 
			_blockSize = blockSize;
		}
 
 
 
		public function work(view:DisplayObject):void
		{
			if (_target) {
				throw new Error('SeparateBuilder is work');
			}
 
			target = view;
		}
 
		public function get bitmapData():BitmapData
		{
			return _cache;
		}
 
		private function set target(value:DisplayObject):void
		{
			_target = value;
 
			_iteration = 0;
 
			_byteArray = new ByteArray();
 
			_cache = new BitmapData(_target.width, _target.height,true);
 
			calculation();
 
			say( SeparateEvent.INIT );
 
			processing();
		}
 
		private function calculation():void
		{
			_map = new Point( 
				Math.floor( target.width / _blockSize ),
				Math.floor( target.height / _blockSize )
			);
 
			if ( target.width > _map.x * _blockSize ) _map.x++;
 
			if ( target.height > _map.y * _blockSize ) _map.y++;
 
			trace( 'Map Sector : ',_map);
		}
 
		private function get target():DisplayObject
		{
			return _target;
		}
 
		private function processing():void
		{
			var sector:Point = new Point(
				_iteration % _map.x,
				Math.floor(_iteration/_map.x) 
			);
 
			snap( sector );
 
			var length:Number = _map.x * _map.y;
			var percent:Number=  100/(length/_iteration);
 
			say( SeparateEvent.PROCESSING , String( Math.floor(percent) )  );
 
			if ( ++_iteration < length ) 
				setTimeout( processing, 1 );
			else 
				complete();
		}
 
		private function snap(sector:Point):void
		{
			var anker:Point = new Point( 
					sector.x*_blockSize,
					sector.y*_blockSize
				);
 
			var zone:Point = new Point(_blockSize,_blockSize);
 
			if ( (anker.x+zone.x) > target.width )  zone.x = target.width - anker.x;
			if ( (anker.y+zone.y) > target.height )  zone.y = target.height - anker.y;
 
			var bd:BitmapData = Extruder.get( target, anker.x, anker.y , zone.x, zone.y );
 
			_cache.copyPixels( bd, bd.rect, anker);
		}
 
		private function complete():void
		{
			_target = null;
 
			say( SeparateEvent.COMPLETE );
		}
 
		private function say(type:String, data:String=''):void {
			this.dispatchEvent( new SeparateEvent( type, data ) );
		}
	}
}
utils.SeparateEvent.as
Код AS3:
package utils
{
	import flash.events.DataEvent;
 
	public class SeparateEvent extends DataEvent
	{
		public static var INIT:String = 'init';
		public static var PROCESSING:String = 'processing';
		public static var COMPLETE:String = 'complete';
 
		public function SeparateEvent(type:String, data:String='')
		{
			super(type, true, false, data);
		}
	}
}
view.RandowView.as
Код AS3:
package view
{
	import flash.display.Sprite;
	import flash.geom.Point;
 
	public class RandomView extends Sprite
	{
		private var _h:Number;
		private var _w:Number;
		public function RandomView(h:Number=5000,w:Number=5000)
		{
			super();
 
			_h = h;
			_w = w;
 
			graphics.beginFill(0xAAAAAA,1);
			graphics.drawRect(0,0,_w,_h);
			graphics.endFill();
 
			var rnd:Number = Math.floor(Math.random()*10)+10;
 
			while (--rnd) draw();
		}
 
		private function draw():void
		{
			var color:uint = Math.random()*0xFFFFFF;
 
			var size:Number = Math.min(_h,_w)*.1;
 
			var body:Point = new Point( Math.random()*(_w-size*2),Math.random()*(_h-size*2));
 
			body.x += size;
			body.y += size;
 
			with (graphics) {
 
				beginFill(color,1);
 
				switch( Math.floor(Math.random()*2) ) {
					case 0:
						drawRect(body.x,body.y, size, size);
					break;
 
					case 1:
						drawCircle(body.x,body.y,size);
					break;
				}
 
				endFill();
			}
		}
	}
}
net.alexscript.hack.Extruder.as
Код AS3:
package net.alexscript.hack {
 
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.PixelSnapping;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
 
	public class Extruder {
 
		public function Extruder() {
 
		}
 
		public static function get( ARG_object:DisplayObject, ARG_x:Number = 0, ARG_y:Number = 0, ARG_width:Number = 0, ARG_height:Number = 0,transpend:Boolean=true):BitmapData {
 
			if (!ARG_width) ARG_width = (ARG_object.mask) ? ARG_object.mask.width : ARG_object.width;
			if (!ARG_height) ARG_height = (ARG_object.mask) ? ARG_object.mask.height : ARG_object.height;
 
			var cropArea:Rectangle = new Rectangle(0, 0, ARG_width, ARG_height);
			var fillColor:uint = transpend
					? 0x00000000
					: 0x0;
			var bmpd:BitmapData = new BitmapData(ARG_width, ARG_height,true,fillColor);
 
			var croppedBitmap:Bitmap = new Bitmap(bmpd, PixelSnapping.ALWAYS, true);
 
			var cropMatrix:Matrix = new Matrix();
			cropMatrix.translate(-ARG_x, -ARG_y);
 
			bmpd.draw( ARG_object, cropMatrix, null, null, cropArea, true );
 
			return bmpd; 
		}
 
	}
 
}
__________________
return this...

Старый 30.05.2015, 19:42
AlexCooper вне форума Посмотреть профиль Отправить личное сообщение для AlexCooper Найти все сообщения от AlexCooper
  № 23  
Ответить с цитированием
AlexCooper
 
Аватар для AlexCooper

Регистрация: Sep 2008
Адрес: Черкассы
Сообщений: 1,167
Записей в блоге: 1
Отправить сообщение для AlexCooper с помощью ICQ Отправить сообщение для AlexCooper с помощью Skype™
P.S. Нативный енкодер так же немного подвисает ( 5000x5000 - 660 ms, 15000х15000 - 5700 ms), если хотите полностью избавиться от подвисания, учите мат.часть используйте copyPixelsToByteArray, после чего пережимайте в jpeg естественно с разделением на блоки

Добавлено через 3 минуты
или же используйте массив мелких JPEG, повырезать из них заголовки, склеить байтерреи и добавить общий заголовок

Добавлено через 36 минут
или
__________________
return this...

Старый 31.05.2015, 01:43
in4core вне форума Посмотреть профиль Отправить личное сообщение для in4core Найти все сообщения от in4core
  № 24  
Ответить с цитированием
in4core
[+4 06.05.14]
 
Аватар для in4core

Регистрация: Mar 2009
Сообщений: 4,219
Записей в блоге: 14
Цитата:
public static function get
страшно
__________________
Марк Tween

Старый 31.05.2015, 01:50
AlexCooper вне форума Посмотреть профиль Отправить личное сообщение для AlexCooper Найти все сообщения от AlexCooper
  № 25  
Ответить с цитированием
AlexCooper
 
Аватар для AlexCooper

Регистрация: Sep 2008
Адрес: Черкассы
Сообщений: 1,167
Записей в блоге: 1
Отправить сообщение для AlexCooper с помощью ICQ Отправить сообщение для AlexCooper с помощью Skype™
Цитата:
Сообщение от in4core Посмотреть сообщение
страшно
Multilock encapsulation on getter
__________________
return this...

Старый 31.05.2015, 22:26
Alex626 вне форума Посмотреть профиль Отправить личное сообщение для Alex626 Найти все сообщения от Alex626
  № 26  
Ответить с цитированием
Alex626

Регистрация: Sep 2010
Сообщений: 167
Щас всё это читаю, изучаю - конечно, сложно. После AS2 и всякого рода игровых интерфейсов, это и правда что-то новенькое. Мозг взорван

Добавлено через 2 часа 58 минут
Примеров масса, и пока что не всё понятно. С нарезкой слишком сложно (я даже тему переименовал), надо очень долго разбираться. Пока что мне подойдёт вариант с кодированием в файл отдельный потоком.

Как я понимаю, в этом случае многопоточность будет использоваться для передачи содержимого моего гигантского спрайта в новый поток, который будет преобразовывать его в JPEG, и отдавать массив байтов обратно, чтобы основной ролик выводил его в FileReference.

Но ведь я не смогу передать целый Sprite на обработку, верно? Т.е. в основном потоке сначала придётся вызвать BitmapData.Draw (что даёт лаг на 3 секунды), чтобы получить его массив байтов, а вот уже BitmapData.encode мжно будет исполнять в другом потоке?


Последний раз редактировалось Alex626; 01.06.2015 в 01:25.
Старый 05.06.2015, 21:55
meiciuc вне форума Посмотреть профиль Отправить личное сообщение для meiciuc Найти все сообщения от meiciuc
  № 27  
Ответить с цитированием
meiciuc

Регистрация: Nov 2005
Сообщений: 149
мне кажется, самым простым вариантом было бы воспользоваться "асинхрннными" декодерами:
там можно задать скорость кодирования.
получать сообщения о прогрессе

в jpg
https://github.com/alinke/DIYMagicMi...syncEncoder.as

в png
http://www.bit-101.com/blog/?p=2581

вот кусок кода из рабочего примера

Код AS1/AS2:
if (_typeEncoding == "jpg") {
						var j:JPEGAsyncEncoder = new JPEGAsyncEncoder(85);
						j.PixelsPerIteration = 300;
						j.addEventListener(JPEGAsyncCompleteEvent.JPEGASYNC_COMPLETE, handleJPEGEncoder);
						j.addEventListener(ProgressEvent.PROGRESS, handleProgress);
						j.encode(_bitmap.bitmapData);
					}
 
					if (_typeEncoding == "png") {
						var p:PNGEncoderAsync = new PNGEncoderAsync();
						p.addEventListener(ProgressEvent.PROGRESS, handleProgress);
						p.addEventListener(Event.COMPLETE, handlePNGEncoder);
						p.encode(_bitmap.bitmapData);
					}

Старый 06.06.2015, 00:11
Alex626 вне форума Посмотреть профиль Отправить личное сообщение для Alex626 Найти все сообщения от Alex626
  № 28  
Ответить с цитированием
Alex626

Регистрация: Sep 2010
Сообщений: 167
Спасибо, сейчас протестирую.

Добавлено через 1 час 48 минут
Опробовал. Круто. Но медленно очень. Беда прям. Вот если бы он работал через обычный энкодер, но в отдельном потоке....


Последний раз редактировалось Alex626; 06.06.2015 в 02:01.
Старый 06.06.2015, 03:03
meiciuc вне форума Посмотреть профиль Отправить личное сообщение для meiciuc Найти все сообщения от meiciuc
  № 29  
Ответить с цитированием
meiciuc

Регистрация: Nov 2005
Сообщений: 149
не знаю, что за конкретная задача стоит, но если картинка действительно большая, то хоть в отдельном потоке, хоть где, время все равно будет занимать существенно много.

может, "обмануть" юзера? на необходимое время повесить для него сообщение, показать прогресс? Это объективно долгий процесс.

разве что, есть библиотека на Алхимии - http://blog.inspirit.ru/async-png-encoding-and-merging/ - но она существенно тоже не поможет - проверено

Старый 06.06.2015, 03:59
Alex626 вне форума Посмотреть профиль Отправить личное сообщение для Alex626 Найти все сообщения от Alex626
  № 30  
Ответить с цитированием
Alex626

Регистрация: Sep 2010
Сообщений: 167
Цитата:
Сообщение от meiciuc Посмотреть сообщение
не знаю, что за конкретная задача стоит, но если картинка действительно большая, то хоть в отдельном потоке, хоть где, время все равно будет занимать существенно много.

может, "обмануть" юзера? на необходимое время повесить для него сообщение, показать прогресс? Это объективно долгий процесс.

разве что, есть библиотека на Алхимии - http://blog.inspirit.ru/async-png-encoding-and-merging/ - но она существенно тоже не поможет - проверено
Крайне большая картинка. Но можно слайдером выбирать масштаб съёмки изображения (т.е. разрешение от мизерного до огромного). Можно, конечно, повесить сообщение. Либо комбо-бокс дать, чтобы предоставить выбор компилера - асинхронный или синхронный. Или как вариант - смотреть на выбранное разрешение - если оно небольшое, то использовать асинхронный энкодер со статус-баром. А если большое, то выдавать блокирующее сообщение и использовать нативный.


А как-то можно обойти ограничение размера BitmapData.Draw? У меня в системе памяти не хватает на масштабы более 234% (это где-то 20.000 х 20.000 пикс.).

Создать новую тему Ответ Часовой пояс GMT +4, время: 08:35.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 08:35.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.