Март 2011

Руководство по actionscript. часть 5, стр. 035

// Получаем значение цвета пиксела, уровень канала Alpha которого // установлен в 255, из прозрачного изображения var imgData-.BitmapData = new BitmapData(20, 20. true. OxFFFFFFFF); trace(imgData. getPixel32(0. 0)); // Выводит: 4294967295

// (исходные данные были сохранены)

Класс ColorPicker: пример использования метода getPixel32()

Теперь, когда мы понимаем, как получить значение цвета пиксела, применим наши знания в реальной ситуации. Предположим, что мы разрабатываем интернет-приложение для создания приглашений на вечеринки. Пользователи приложения сначала выбирают фотографию, которая будет помещена на приглашение, а затем задают подходящий цвет для текста приглашения. Чтобы пользователь мог поэкспериментировать с различными цветами, приложение предоставляет специальную форму для выбора цвета. Когда пользователь перемещает указатель мыши над выбранным изображением, цвет текста приглашения автоматически изменяется в соответствии с цветом пиксела, над которым в данный момент находится указатель мыши. В листинге 26.4 продемонстрирован код для палитры выбора цвета с тестовым изображением sunset. jpg. Изучите комментарии, чтобыпонять, как происходит получение значения цвета под указателем мыши.

Листинг 26.4. Палитра выбора цвета на основе изображения

package { import flash. display.*; import flash. events.*; import flash. text.*; import flash. net.*;

// Устанавливает цвет объекта TextField в соответствии с цветом

// выбранного в изображении пиксела.

public class ColorPicker extends Sprite { private var img:Bitmap; // Объект Bitmap

private var imgContainer:Sprite; // Контейнер для объекта Bitmap private var t:TextField; // Раскрашиваемый объект TextField

// Метод-конструктор

public function ColorPicker( ) {

// Создаем объект TextField и добавляем его в иерархию отображения

// объекта ColorPicker

t = new TextField( );

t. text = «Please come to my party…»;

t. autoSize = TextFieldAutoSize. LEFT;

addChild(t);

// Загружаем изображение

var loader-.Loader = new Loader ( );

1oader. contentLoaderInfо. addEventLi stener(Event. INIT,

initListener);

1oader.1oad(new URLRequest(«sunset. jpg»));

}

// Вызывается, когда инициализация изображения завершена private function initListener (e:Event):void {

// Получаем ссылку на загруженный объект Bitmap

img = е. target. content;

// Помещаем загруженное растровое изображение в объект Sprite, чтобы // мы могли реагировать на взаимодействия с мышью imgContainer = new Sprite( ); i mgConta i ner. addChi1d(i mg);

// Добавляем объект Sprite в иерархию отображения объекта ColorPicker addChild(imgContainer); imgContainer. у = 30;

// Регистрируем приемник для получения уведомлений о перемещении мыши imgContainer. addEventLi stener(MouseEvent. M0USE_M0VE, mouseMoveListener);

}

// Вызывается, когда происходит перемещение мыши над объектом Sprite. // содержащим изображение

private function mouseMoveListener (e:MouseEvent):void { // Устанавливаем цвет текста в соответствии с цветом пиксела, // находящегося в данный момент под указателем мыши

t. textColor = img. bitmapData. getPixel32(e. localX, e. localY);

}

}

}

Получение цвета области пикселов

Методыэкземпляраде1Р1хе132 ( ) иgetPixel ( ) класса BitmapData применяются для получения значения цвета отдельного пиксела. В отличие от этого, метод экземпляра getPixels ( ) класса BitmapData используется для получения значений цвета целой прямоугольной области пикселов. Метод getPixels ( ) может быть использован в любом из следующих сценариев:

? при передаче области растрового изображения между модулями программы;

? при использовании собственного алгоритма для обработки фрагмента растрового изображения;

? при отправке фрагмента или всего растрового изображения на сервер в необработанном бинарном формате.

Руководство по actionscript. часть 5, стр. 036

Метод getPixels ( ) принимает следующий обобщенный вид:

объектаtmapData. getPi xels(область)

Здесь объектВтtmapData — объект BitmapData, из которого будут возвращаться значения цвета пикселов, а область — объект flash. geom. Rectangle, описывающий область возвращаемых пикселов. Метод getPixels ( ) возвращает объект ByteArray, содержащий 32-битные целочисленные значения цвета. Объект ByteArray — это список значений цвета для пикселов в указанной прямоугольной области, обход которых происходит слева направо и сверху вниз. Например, рассмотрим следующую диаграмму растрового изображения размером 4×4, пикселы которого для простоты обозначены буквами от А до Р:

А В С D Е F G Н I J К L М N О Р

Не забывая, что пиксел левого верхнего угла растрового изображения находится в точке с координатой (0; 0), если мы воспользуемся методом getPixels ( ) для получения значений цвета прямоугольной области пикселов от точки (2; 1) до точки (3; 3), возвращаемый объект ByteArray будет содержать следующие пикселы в таком порядке:

G, Н. К, L, 0. Р

Стоит отметить, что объект ByteArray представляет собой одномерный список и не содержит никакой информации о размерах и позиции прямоугольной области, из которой были получены данные пикселы. Таким образом, чтобы восстановить растровое изображение из пикселов, хранящихся в объекте ByteArray, в том порядке, в котором они находились ранее, мы должны иметь свободный доступ к ширине, высоте и позиции исходного прямоугольника. Информация об исходном прямоугольнике может быть присвоена переменной или даже добавлена в сам объект ByteArray.

Чтобы попрактиковаться в использовании метода get Pixel s ( ), скопируем прямоугольную область из одного растрового изображения в другое изображение. Сначала мы создадим два объекта BitmapData. Первый объект представляет квадрат синего цвета размером 20 х 20 пикселов, а другой — квадрат зеленого цвета размером 30 х 30 пикселов:

var blueSquare:BitmapData = new BitmapData(20. 20. false. OxFFOOOOFF); var greenSquare:BitmapData = new BitmapDataOO. 30. false. OxFFOOFFOO);

Затем мы определяем прямоугольную область пикселов, которую хотим получить из квадрата зеленого цвета. Левый верхний угол прямоугольника находится в точке с координатой (5; 5), а его ширина и высота равна 10 пикселам.

var rectRegion:Rectangle = new Rectangle(5. 5. 10. 10);

Теперь мы получаем пикселы зеленого цвета:

var greenPixels:ByteArray = greenSquare. getPixels(rectRegion);

Чтобы перенести пикселы зеленого цвета на квадрат синего цвета, мы используем метод экземпляра set Pixels ( ) класса BitmapData. Однако перед вызовом метода set Pixel s ( ) мы должны установить указатель файла объекта ByteArray в значение 0, чтобы метод setPixels( ) начал чтение значений цвета пикселов с начала списка:

greenPixels. position = 0;

Теперь мы можем прочитать пикселы из объекта ByteArray greenPixels и сохранить их в объекте BitmapData blueSquare:

blueSquare. setPi xels(rectRegi on. greenPi xels);

Чтобы убедиться, что все работает так, как ожидалось, мы отображаем два растровых изображения на экране:

var blueBmp:Bitmap = new Bitmap(blueSquare); var greenBmp:Bitmap = new Bitmap(greenSquare); addChild(blueBmp); addChild(greenBmp); greenBmp. x = 40;

На рис. 26.5 показаны результаты выполнения предыдущего кода.

Руководство по actionscript. часть 5, стр. 037

Рис. 26.5. Пикселы, скопированные из объекта ByteArray

Если при копировании пикселов между двумя растровыми изображениями размеры копируемого прямоугольника и целевого прямоугольника совпадают (как в предыдущем примере), мы можем использовать удобный метод экземпляра copyР ixe 1 s ( ) клaccaBitmapDataвмecтoкoмбинaциимeтoдoвgetPixels ( ) HsetPixels( ). К другим внутренним методам экземпляра класса BitmapData, предоставляющим удобный доступ к типичным операциям копирования, относятся: copyChannel ( ), clone ( ), merge ( ) и draw ( ). Дополнительную информацию можно найти далее, в разд. «Копирование графики в объект BitmapData» этой главы.

Другие инструменты анализа

В этом разделе мы узнали, как анализировать пикселы объекта BitmapData, используя методы getPixel32 ( ), getPixel ( ) и getPixels ( ). Кроме того класс BitmapData предоставляет несколько других, более специализированных инструментов для анализа пикселов:

? compare ( ) — проверяет, есть ли отличие между пикселами двух растровых изображений;

? getColorBoundsRect ( ) — определяет, какая область растрового изображения содержит указанный цвет;

? hitTest ( ) — определяет, перекрывают ли пикселы растрового изображения некоторую точку, прямоугольник или другое растровое изображение.

Подробную информацию о перечисленных методах можно найти в описании класса BitmapData в справочнике по языку ActionScript корпорации Adobe.

Внесение изменений в растровое изображение

Основные инструменты для присваивания новых цветов пикселам существующего растрового изображения являются точным отражением инструментов, предназначенных для анализа растрового изображения. К ним относятся методы setPixel32 ( ), setPixel ( ) и setPixels ( ). Метод setPixel32 ( ) присваивает новое четырехканальное значение цвета пикселу в виде 32-битного целого числа. Он принимает следующий вид:

объектШtmapData. setPixe!32(x, у, цвет)

Здесь обьектВ! tmapData — экземпляр класса BitmapData, содержащий пиксел, значение цвета которого будет изменяться; х и у — горизонтальная и вертикальная позиции данного пиксела; цвет — новое значение цвета, присваиваемое пикселу. Например, следующий код создает растровое изображение, представляющее квадрат синего цвета, и затем присваивает его левому верхнему пикселу значение белого цвета:

var imgData:BitmapData = new BitmapData(20, 20. false. OxFFOOOOFF); imgData. setPixel32(0. 0. OxFFFFFFFF);

В отличие от этого, метод setPixel ( ), который принимает такой же общий вид, как и метод setPixel32( ), устанавливает только значения каналов Red, Green и Blue цвета пиксела, не изменяя исходное значение канала Alpha. Например, следующий код создает полупрозрачное растровое изображение, представляющее квадрат синего цвета, и затем присваивает его левому верхнему пикселу значение белого цвета. Поскольку вместо метода setPixel32( ) используется setPixel ( ), левый верхний пиксел сохраняет свое исходное значение канала Alpha (Охбб):

var imgData:BitmapData = new BitmapData(20. 20, true. 0x660000FF); imgData. setPixeKO. 0. OxFFFFFF):

После завершения операции set Pixel ( ) значением цвета левого верхнего пиксела будет являться число Охб 6FFFFFF.

Руководство по actionscript. часть 5, стр. 038

Любое значение канала Alpha, указываемое в числе, которое передается в метод setPixel ( ), будет проигнорировано. Например, в следующем коде мы присваиваем значение цвета пиксела, используя число, в котором для канала Alpha указано значение сс. Несмотря на это, после завершения операции значением цвета левого верхнего пиксела по-прежнему будет являться число 0x66FFFFFF:

imgData. setPixeKO. 0. OxCCFFFFFF);

Повышение производительности с помощью метода BitmapData. lockC)

По умолчанию, всякий раз, когда над некоторым объектом BitmapData вызывается метод setPixel32 ( ) или setPixel ( ), экземпляры класса Bitmap, ссылающиеся на этот объект, получают уведомление об изменении данных. Когда методы setPixel32( ) или setPixel ( ) вызываются друг за другом внутри одного цикла кадра (например, когда каждому пикселу в растровом изображении присваивается значение цвета), подобные уведомления могут привести к снижению производительности. Для повышения производительности мы можем использовать метод экземпляра lock ( ) класса BitmapData.

Вызов метода lock ( ) над объектом BitmapData запрещает среде выполнения Flash уведомлять зависимые объекты В i tmap при вызове методов setPixel32( ) или setPixel ( ). Таким образом, если вы собираетесь использовать методы setPixel32 ( ) или setPixel ( ) друг за другом, всегда вызывайте метод lock ( ). После его вызова присвойте все желаемые значения цвета пикселов; затем вызовите метод экземпляра unlock ( ) класса BitmapData. Метод unlock ( ) позволяет среде Flash при необходимости уведомить все зависимые объекты Bitmap.

Данный подход продемонстрирован в листинге 26.5. В этом коде используется цикл для присваивания случайного цвета каждому пикселу в объекте BitmapData размером 500 х 500 пикселов. Обратите внимание на вызов метода lock ( ) перед циклом и вызов метода unlock ( ) после цикла, выделенные полужирным шрифтом.

Листинг 26.5. Использование метода BitmapData. lock() для повышения производительности

// Создаем растровое изображение

var imgData:BitmapData = new BitmapData(500. 500. true. 0×00000000); var bmp:Bitmap = new Bitmap(imgData);

// Вызываем метод lock( ) imgData. lock( );

// Устаналиваем значения цвета пикселов var col or:uint;

for (var i:int = 0; i < imgdata.height ; i++) { for (var j:int = 0; j < imgdata.width; j++) { color = math.f1oor(math.random( )*0xffffffff); imgdata.setpixel32(j, i, color);

}

}

// Вызываем метод unlock( ) imgData. unlock( );

При тестировании кода из листинга 26.5 в рабочей версии приложения Flash Player на компьютере с процессором Pentium 4 2,6 ГГц одна итерация цикла занимает приблизительно 100 мс. Без использования метода lock ( ) одна итерация занимает примерно 125 мс. Иными словами, при использовании метода lock ( ) код выполняется приблизительно на 20 % быстрее.

Руководство по actionscript. часть 5, стр. 039

При измерении производительности среды Flash всегда выполняйте тесты в рабочей, а не в отладочной версии. Производительность в рабочей версии приложения зачастую оказывается в два раза выше, чем в отладочной.

Класс ScribbleASS: пример использования метода setPixel32()

Присваивание цвета пикселу в растровом изображении имеет множество практических применений: от создания собственных эффектов до коррекции фотографий или генерации динамического интерфейса. Рассмотрим всего одно практическое применение метода set Pixel 32 ( ) — простую программу для рисования. В листинге 26.6 представлена адаптация на языке ActionScript 3.0 программы Scribble. Выполнение этого кода приводит к созданию пустого растрового изображения, на котором пользователь рисует линии с помощью мыши. Когда пользователь перемещает мышь, удерживая нажатой левую кнопку, на пустом растровом изображении рисуется пиксел черного цвета.

Листинг 26.6. Очень простая программа рисования ScribbleAS3

package {

import flash. display.*; import flash. events.*; import flash. ui.*; import flash. geom.*;

// Простое приложение для рисования. Рисует одну точку на объекте

// BitmapData всякий раз, когда возникает событие MouseEvent. M0USE_M0VE

// при нажатой левой кнопке мыши.

public class ScribbleAS3 extends Sprite {

// Растровое изображение, отображаемое на экране

private var canvas:Bitmap;

// Содержит растровое изображение, обеспечивая интерактивность private var canvasContaiпег:Sprite;

// Линия вокруг растрового изображения private var border:Shape;

// Сообщает о том, нажата ли кнопка мыши в настоящий момент private var isDrawing:Boolean = false;

// Конструктор

public function SeribbleAS3 ( ) { createCanvas( ); registerForInputEvents( );

// Предотвращаем изменение размеров окна приложения stage. scaleMode = StageScaleMode. N0_SCALE:

}

// Создает пустое растровое изображение, на котором будем рисовать private function createCanvas (width:int = 200, height:int = 200):void {

// Определяем объект BitmapData, который будет хранить пиксельные

// данные для рисунка пользователя

var canvasData:BitmapData = new BitmapData(width, height,

false. OxFFFFFFFF);

// Создаем новый отображаемый объект Bitmap, используемый // для отображения объекта canvasData canvas = new Bitmap(canvasData);

// Создаем объект Sprite, который будет содержать объект Bitmap. Класс // Bitmap не поддерживает события ввода; следовательно, помещаем его // в объект Sprite, чтобы пользователь мог взаимодействовать с этим // объектом.

Руководство по actionscript. часть 5, стр. 040

CanvasContainer = new SpriteC );

// Добавляем растровое изображение bitmap в экземпляр canvasContainer // класса Sprite

canvasContai ner. addChi1d(canvas);

// Добавляем экземпляр canvasContainer класса Sprite (и содержащийся // в нем объект Bitmap) в иерархию отображения данного объекта addChild(canvasContai пег);

// Создаем границу вокруг области рисования, border = new ShapeC ); border. graphics. lineStyled, OxFFOOOOOO); border. grapnics. drawRect(0, 0, width, height); addChild(border);

}

// Регистрирует приемники для необходимых событий мыши и клавиатуры

private function registerForlnputEvents ( ):void { // Регистрируем приемники для событий нажатия кнопки мыши // и перемещения мыши от объекта canvasContainer canvasContai ner. addEventLi stener(MouseEvent. M0USE_D0WN,

mouseDownListener);

canvasContai ner. addEventLi stener(MouseEvent. M0USE_M0VE,

mouseMoveListener);

// Регистрируем приемники для событий отпускания кнопки мыши и нажатия

// клавиши от объекта Stage (то есть для глобальных событий).

Руководство по actionscript. часть 5, стр. 041

// Используем объект Stage, поскольку событие отпускания кнопки мыши

// должно всегда завершать рисование, даже если указатель мыши

// не находится над областью рисования. Подобным образом нажатие

// пробела должно всегда приводить к стиранию рисунка, даже когда

// объект canvasContainer не имеет фокуса.

stage. addEventLi stener(MouseEvent. MOUSEJJP, mouseUpLi stener);

stage. addEventLi stener(KeyboardEvent. KEY_D0WN, keyDownLi stener);

}

// Устанавливает цвет указанного пиксела

public function drawPoint (x:int, y:int, colonuint = OxFFOOOOOO):void { canvas. bitmapData. setPixel32(x, y, color);

}

// Отвечает на события MouseEvent. MOUSE JDOWN

private function mouseDownListener (e:MouseEvent):void {

// Устанавливаем флажок, указывающий на то, что основная кнопка мыши

// в настоящий момент нажата

isDrawing = true;

// Рисуем точку в позиции, где произошел щелчок кнопкой мыши. drawPoint(е.1ocalX, е. localY);

}

// Отвечает на события MouseEvent. M0USE_M0VE

private function mouseMoveListener (e:MouseEvent):void {

// Рисуем точку, когда мышь перемещается над областью рисования

// при нажатой левой кнопке мыши

if (isDrawing) {

// Используем переменные 1ocalX и localY, чтобы получить позицию // указателя относительно объекта canvasContainer. drawPoi nt(е.1ocalX, е. localY);

// Обновляем экран сразу после завершения выполнения // данной функции-приемника события е. updateAfterEvent( );

}

// Отвечает на события MouseEvent. MOUSEJJP

private function mouseUpListener (e:MouseEvent):void {

// Устанавливаем флажок, указывающий на то, что в настоящий момент

// основная кнопка мыши отпущена

isDrawing = false;

}

// Отвечает на события KeyboardEvent. KEYJDOWN

private function keyDownListener (e:KeyboardEvent):void {

// Стираем рисунок, когда пользователь нажимает клавишу Пробел. Чтобы // очистить рисунок, мы присваиваем всем пикселам значение белого // цвета.

Руководство по actionscript. часть 5, стр. 042

If (е. charCode == Keyboard. SPACE) { canvas. bitmapData. fillRect(new Rectangle(0, 0,

canvas. width, canvas. height), OxFFFFFFFF);

}

}

}

}

Присваивание цвета области пикселов

Методы setPixel32( )nsetPixel( ) используются для присваивания значения цвета отдельному пикселу. В отличие от этого, метод экземпляра setPixels( ) класса BitmapData применяется для присваивания значений цвета целой прямоугольной области пикселов.

Метод setPixels ( ) имеет следующий обобщенный вид:

o6beKTBitmapData. setPixels(область, пикселыВуЬеАггау)

Здесь обьектВПшарОаЬа — объект BitmapData, пикселам которого присваиваются значения цвета, область — объект flash. geom. Rectangle, описывающий область пикселов, которым будет присвоен цвет, а пикселыВуЬеАггау — объект ByteArray, содержащий беззнаковые 32-битные целые числа, определяющие присваиваемые значения цвета.

Руководство по actionscript. часть 5, стр. 043

Метод setPixels( ) заполняет указанную прямоугольную область в направлении слева направо и сверху вниз, начиная со значения цвета объекта пикселыВуЬеАггау, находящегося в текущей позиции указателя файла (то есть в позиции пикселыВуЬеАггау. position).

Например, рассмотрим следующую диаграмму растрового изображения размером 4×4, пикселы которого для простоты обозначены буквами от А до Р:

А В С D Е F G Н I J К L М N О Р

Теперь рассмотрим следующую диаграмму массива байт, содержащего шесть 32-битных беззнаковых целочисленных значений цвета, обозначенных символами от С1 до С6:

CI С2 СЗ С4 С5 С6

Не забывайте, что пиксел левого верхнего угла растрового изображения находится в точке с координатой (0; 0). Если мы воспользуемся методом setPixels ( ) для заполнения прямоугольной области пикселов от точки (1; 0) до точки (3; 1) с помощью предыдущего массива байт, растровое изображение будет выглядеть следующим образом:

A CI С2 СЗ Е С4 С5 Сб I J К L М N 0 Р

Попробуем проделать то же самое в коде. Сначала создадим квадрат красного цвета размером 4×4 пиксела:

var imgData:BitmapData = new BitmapData(4, 4, false, OxFFFFOOOO);

Теперь мы создадим массив байт, который содержит шесть значений цвета — все они обозначают зеленый цвет. Для демонстрационных целей мы создадим массив байт вручную, однако обычно он формируется программным путем, возможно, с помощью вызова метода getPixels ( ) или в результате выполнения пользовательского алгоритма, возвращающего значения цвета. Массив будет выглядеть следующим образом:

var byteArray:ByteArray = new ByteArray( ); byteArray. writeUnsignedlnt(OxFFOOFFOO); byteArray. writeUnsignedInt(OxFFOOFFOO); byteArray. writeUnsignedlnt(OxFFOOFFOO); byteArray. writeUnsignedlnt(OxFFOOFFOO); byteArray. writeUnsignedlnt(OxFFOOFFOO); byteArray. writeUnsignedlnt(OxFFOOFFOO);

Далее мы устанавливаем позицию, с которой метод set Pixels ( ) должен начать чтение значений цвета из массива байт. Мы хотим, чтобы метод setPixels ( ) начаЛ чтение с самого начала массива байт, поэтому присваиваем переменной экземпляра position класса ByteArray значение 0: byteArray. position = 0;

Наконец, заполняем прямоугольную область в растровом изображении цветами та тшлъъ (й&тл

imgData. setPixels(new Rectangled.0,3,2), byteArray);

I Обратите внимание, что позиция и размеры объекта Rectangle, передаваемого в метод м$ 4 * setPixels(), определяются с помощью координаты левого верхнего угла и ширины/высоты _ Щх прямоугольника, а не координат левого верхнего угла и правого нижнего угла.

Руководство по actionscript. часть 5, стр. 044

Стоит отметить, что, если данные в объекте пикселыВуЬеАггау закончатся до того, как будет заполнена указанная прямоугольная область, среда выполнения Flash сгенерирует исключение EOFError. Например, если мы увеличим размер предыдущей прямоугольной области с 3 х 2 пиксела (6 пикселов) до 3 х 3 пиксела (9 пикселов) следующим образом:

imgData. setPixels(new Rectangled,0,3,3), byteArray);

произойдет следующая ошибка:

Error: Error #2030: End of file was encountered.

На русском языке она будет звучать так: Ошибка #2030: достигнут конец файла.

Кроме того, подобная ошибка может возникнуть, если после создания объекта ByteArray мы забудем установить его позицию в 0 (что является гораздо более

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

I Перед вызовом метода setPixels() не забывайте устанавливать позицию указываемого м$ а • входного массива байт.

Метод setPixels ( ) обычно применяется для создания растрового изображения на основе сериализованных бинарных данных, полученных из некоторого внешнего источника, например сервера или совместно используемого локального объекта.

Другие инструменты изменения изображений

В этом разделе мы узнали, как можно изменять пикселы в объекте BitmapData с помощью методов setPixel32 ( ), setPixel ( ) и setPixels ( ). Класс BitmapData также предоставляет несколько других, более специализированных инструментов для работы с пикселами:

? fillRect ( ) — присваивает заданный цвет пикселам из прямоугольной области;

? floodFill ( ) — присваивает заданный цвет всем пикселам, окружающим некоторый пиксел р, цвет которых соответствует цвету данного пиксела (подобно инструменту заливки, который присутствует во многих программах для работы с графикой);

? scroll ( ) — изменяет позицию всех пикселов растрового изображения на заданную величину по горизонтали и вертикали.



Полезные ссылки
Случайные записи
  • 09.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.164
  • 15.06.2010">Самоучитель по креативному веб-дизайну. Книга 4, стр.49
  • 04.03.2011">Руководство по actionscript. часть 5, стр. 030
  • 23.07.2011">Дизайнеры помогут преобразить любое жилье
  • 12.03.2011">Руководство по actionscript. часть 3, стр. 130
  • 22.03.2011">Руководство по actionscript. часть 2, стр. 003
  • 23.01.2011">Руководство по actionscript. часть 1, стр. 043
  • 08.03.2011">Руководство по actionscript. часть 4, стр. 095
  • 18.03.2011">Руководство по actionscript. часть 2, стр. 133
  • 27.08.2011">Размещение сервера в датацентре
  • 16.06.2010">Самоучитель по креативному веб-дизайну. Книга 4, стр.15
  • 16.03.2011">Руководство по actionscript. часть 3, стр. 014
  • 09.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.134
  • 16.03.2011">Руководство по actionscript. часть 3, стр. 033
  • 18.05.2010">Самоучитель по креативному веб-дизайну. Книга 2, стр.43
Опрос

Какие цвета вы предпочитаете?

View Results

Loading ... Loading ...