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

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

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 30.11.2006, 14:48
NewMan_by вне форума Посмотреть профиль Отправить личное сообщение для NewMan_by Найти все сообщения от NewMan_by
  № 1  
Ответить с цитированием
NewMan_by
 
Аватар для NewMan_by

Регистрация: Aug 2005
Сообщений: 64
По умолчанию Pixelization

Необходимо сделать данный эффект http://http://www.infosci.cornell.ed...on-15pixel.jpg
собственно нужна помощь по алгоритму для него или вообще любая в этом плане.

Старый 30.11.2006, 15:26
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 2  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
Я бы делал так:
Делишь картинку на блоки, считываешь каждый блок BitmapData.getPixels в ByteArray. Пробегаешься по ByteArray высчитывая средне-арифметический цвет. Заливаешь весь ByteArray этим цветом, кладешь блок назад в картинку BitmapData.setPixels
На первый взгляд ничего сложно...
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.

Старый 30.11.2006, 17:15
WindWalker вне форума Посмотреть профиль Отправить личное сообщение для WindWalker Найти все сообщения от WindWalker
  № 3  
Ответить с цитированием
WindWalker
[+1 18.03.08]

Регистрация: Nov 2006
Сообщений: 223
Могу предложить 2 варианта, совместимых с AS2.0 и ниже.
Насчёт скорости ничего сказать не могу.

1. Используем DispacementMapFilter и специально построенную карту трансформации.

Правда, при этом цвет каждого квадрата будет не средним арифметическим всех содержащихся в нём пикселей, а будет выбран какой-то один конкретный пиксель и его цвет будет назначен всему квадрату.
Кроме того, требуется создавать аналогичный по размеру битмап.
Хорошо подходит для случая, когда начальная картинка содержится в мувиклипе.

2. Начальное изображение сперва уменьшаем, записываем в битмап, затем снова увеличиваем.
Требуется временный битмап для трансформаций, но на порядок меньшего размера.
Хорошо подходит для случая, когда картинка изначально содержится в битмапе.

Примеры.

Подготовительный этап (одинаковый для обоих)
Код:
import flash.display.*;
import flash.geom.*;
import flash.filters.*;

// ПОДГОТОВКА

// создаём битмапы: начальный и конечный
bmp1 = new BitmapData(100,100,false,0);
bmp2 = new BitmapData(100,100,false,0);

// создаём мувики для отображения битмапов
_root.createEmptyMovieClip("mcHolder1",0);
_root.createEmptyMovieClip("mcHolder2",1);
mcHolder1.attachBitmap(bmp1,0);
mcHolder2.attachBitmap(bmp2,0);
mcHolder2._x = 150;

// заполняем начальный битмап зелёным градиентом
for (var x=0; x<100; x++) {
	for (var y=0; y<100; y++) {
		bmp1.setPixel(x,y,(x+y)<<8);
	}
}
Первый алгоритм:
Код:
// заполняем карту трансформации
var bmpMap = new BitmapData(100,100);
for (var x=0; x<100; x++) {
	for (var y=0; y<100; y++) {
		bmpMap.setPixel(x,y,0x8080-(x%10<<8)-(y%10));
	}
}

var filter = new DisplacementMapFilter(bmpMap, new Point(0,0), 2, 4, 256, 256);
bmp2.applyFilter(bmp1,bmp1.rectangle,new Point(0,0),filter);
Второй алгоритм:

Код:
// создаём временный битмап
bmpTemp = new BitmapData(10,10);

// подготовливаем матрицы для преобразования
m1 = new Matrix();
m1.scale(1/10,1/10);
m2 = new Matrix();
m2.scale(10,10);

// уменьшаем
bmpTemp.draw(bmp1,m1);
// увеличиваем
bmp2.draw(bmpTemp,m2);


Последний раз редактировалось WindWalker; 30.11.2006 в 17:31.
Старый 30.11.2006, 19:57
NewMan_by вне форума Посмотреть профиль Отправить личное сообщение для NewMan_by Найти все сообщения от NewMan_by
  № 4  
Ответить с цитированием
NewMan_by
 
Аватар для NewMan_by

Регистрация: Aug 2005
Сообщений: 64
MerlinTwi я попровал ка ты говорил через среднее арифметическое, не то! Цвет уж очень какой то страшно далекий от то что должно быть. Может я не верно считаю среднее арифметическое. То есть я беру сумму цветов и делю на их кол-во
Код:
 
while (_byteArray.position < _byteArray.length) {
	k++;
	str=_byteArray.readUnsignedInt().toString(16);
	str=str.substring(2,str.length);
	_color+=int("0x"+str);
}
_color=_color/k;
_color=uint("0xff"+_color.toString(16));
Может кто подскажет как лучше вычислять конечный "общий" цвет?

Старый 01.12.2006, 03:31
FlexBuilder вне форума Посмотреть профиль Отправить личное сообщение для FlexBuilder Найти все сообщения от FlexBuilder
  № 5  
Ответить с цитированием
FlexBuilder

Регистрация: Aug 2006
Сообщений: 70
эге, надо ведь покомпонентно смешивать

Старый 01.12.2006, 12:30
BlooDHounD вне форума Посмотреть профиль Отправить личное сообщение для BlooDHounD Посетить домашнюю страницу BlooDHounD Найти все сообщения от BlooDHounD
  № 6  
Ответить с цитированием
BlooDHounD
стервочка (я мужик)
 
Аватар для BlooDHounD

блогер
Регистрация: Mar 2004
Адрес: Борисов
Сообщений: 3,161
Записей в блоге: 22
тебе надо посчитать не среднее число цвета, а средние числа его составляющих. тоесть R отдельно G отдельно и B отдельно. а у тя получается ваще фиг знает какое число. явно не то что тебе нужно

Старый 01.12.2006, 13:38
WindWalker вне форума Посмотреть профиль Отправить личное сообщение для WindWalker Найти все сообщения от WindWalker
  № 7  
Ответить с цитированием
WindWalker
[+1 18.03.08]

Регистрация: Nov 2006
Сообщений: 223
Что-то я не понял, зачем переводишь в строку и обратно? Это же медленно!
Лучше воспользуйся битовыми операциями.

Код:
r = 0;
g = 0;
b = 0;
while (_byteArray.position < _byteArray.length) {
	k++;
	c = _byteArray.readUnsignedInt();
	r += (c & 0xff0000)>>16;  // это красная составляющая
	g += (c & 0xff00)>>8;  // это зелёная составляющая
	b += c & 0xff;  // это синяя составляющая
}
_color= ((r/k) << 16) + ((g/k) << 8) + b/k;

Старый 01.12.2006, 13:51
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 8  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
Цитата:
Сообщение от NewMan_by
MerlinTwi я попровал ка ты говорил через среднее арифметическое, не то! Цвет уж очень какой то страшно далекий от то что должно быть.
. . .
Может кто подскажет как лучше вычислять конечный "общий" цвет?
Тебе правильно заметили, ты суммируешь все в одну кучу
В массиве ByteArray цвет одной точки сохраняется в 4 байта: прозрачность, красный, зеленый, синий
Надо суммировать каждый байт отдельно. Ниже см. пример.

А чем не подходит метод с уменьшением и увеличением картинки? Во-первых быстрее, во-вторых меньше кода. Я-то вариант с byteArray привел только как пример использования новых методов AS3 для решения этой задачи (это ведь форум по AS3 ;-)

Код:
// размеры картинки
var w:int = 200;
var h:int = 200;
var step:int = 16; // размер блока пикселизации
// нарисуем что-нибудь градиентное
var s:Shape = new Shape();
var matr:Matrix = new Matrix();
matr.createGradientBox(w, h, 20, 0, 0);
s.graphics.beginGradientFill(GradientType.LINEAR, [0x0000FF, 0x00FF00], [100, 100], [0x00, 0xFF], matr);
s.graphics.drawRect(0,0,w,h);
s.graphics.endFill();
addChild(s);

// Создаем BitmapData с картинкой
var bd:BitmapData = new BitmapData(w,h);
bd.draw(s);
addChild(new Bitmap(bd)).x = w + 10;

var tm:Number = getTimer(); // посчитаем сколько времени это займет
for (var y1:int=0; y1<h; y1+=step) {
	for (var x1:int=0; x1<w; x1+=step) {
		// считываем блок
		var b:ByteArray = bd.getPixels(new Rectangle(x1,y1,step,step));
		b.position=0;
		var alph:int=0, red:int=0, green:int=0, blue:int=0, cnt:int=0;
		while (b.bytesAvailable) {
			alph += b.readUnsignedByte();
			red += b.readUnsignedByte();
			green += b.readUnsignedByte();
			blue += b.readUnsignedByte();
			cnt++;
		}
		// усредняем цвет
		alph /= cnt;
		red /= cnt;
		green /= cnt;
		blue /= cnt;
		// заполняем массив
		b.position=0;
		while (cnt--) {
			b.writeByte(alph);
			b.writeByte(red);
			b.writeByte(green);
			b.writeByte(blue);
		}

		// записываем массив обратно в картинку
		b.position=0;
		bd.setPixels(new Rectangle(x1,y1,step,step), b);
	}
}
trace("Time bytearray:", getTimer()-tm);

//------------------------------------------------------------
// Теперь попробуем метод с уменьшением и увеличением картинки
var bmp2:BitmapData = new BitmapData(w,h);
addChild(new Bitmap(bmp2)).y = h+ 10;

// создаём временный битмап
var bmpTemp:BitmapData = new BitmapData(w,h);

// подготовливаем матрицы для преобразования
var m1:Matrix = new Matrix();
m1.scale(1/step,1/step);
var m2:Matrix = new Matrix();
m2.scale(step,step);

tm = getTimer();
// уменьшаем
bmpTemp.draw(s,m1);
// увеличиваем
bmp2.draw(bmpTemp,m2);
trace("Time resize:", getTimer()-tm);
P.S. В результате теста обнаружился баг: если размер блока не кратен размеру картинки, то в варианте уменьшения-увеличения картинки справа и внизу видны артефакты
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.

Старый 01.12.2006, 17:12
NewMan_by вне форума Посмотреть профиль Отправить личное сообщение для NewMan_by Найти все сообщения от NewMan_by
  № 9  
Ответить с цитированием
NewMan_by
 
Аватар для NewMan_by

Регистрация: Aug 2005
Сообщений: 64
Я релиазивал первый вариант который привел WindWalker и он работает вполне подходяще и быстро. Спасибо WindWalker!

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

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

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


 


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


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