Тема: Pixelization
Показать сообщение отдельно
Старый 01.12.2006, 13:51
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 4  
Ответить с цитированием
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
Я возьму сам.