Руководство по 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 ( ) — изменяет позицию всех пикселов растрового изображения на заданную величину по горизонтали и вертикали.

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

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

Класс BitmapData также поддерживает различные фильтры, эффекты и операции копирования, которые могут быть использованы для управления пикселами растрового изображения. Дополнительную информацию можно получить далее, в разд. «Копирование графики в объект BitmapData» и «Применение фильтров и эффектов» этой главы.

Изменение размеров растрового изображения

Когда изменяются размеры объекта Bitmap, ссылающегося на объект BitmapData, с помощью переменных scaleX и scaleY или width и height, размеры изображения на экране меняются, однако нижележащий объект BitmapData остается неизменным. Чтобы изменить размер нижележащего объекта BitmapData на самом деле, мы должны произвести его повторную выборку с помощью метода экземпляра draw ( ) класса BitmapData {повторная выборка означает изменение числа пикселов в изображении). Общая методика выглядит следующим образом.

1. Получить ссылку на исходный объект BitmapData.

2. Нарисовать масштабированную версию исходного объекта BitmapData в новом объекте BitmapData.

3. Наконец, связать исходный объект Bitmap с новым, масштабированным объектом BitmapData.

Перечисленные шаги продемонстрированы в листинге 26.7.

Листинг 26.7. Повторная выборка растрового изображения

// Получаем временную ссылку на исходный объект BitmapData var originalBitmapData:BitmapData = originalBitmap. bitmapData;

// Устанавливаем величину, которая будет определять коэффициент // масштабирования растрового изображения var scaleFactonNumber = .5:

// Вычисляем новые размеры масштабированного растрового изображения var newWidth:int = originalBitmapData. width * scaleFactor, var newHeight;int = originalBitmapData. height * scaleFactor;

// Создаем новый объект BitmapData, размеры которого позволят уместить // масштабированное растровое изображение

var scaledBitmapData:BitmapData = new BitmapData(newWidth, newHeight,

ori gi nalBitmapData. transparent);

// Создаем матрицу преобразований, с помощью которой будет происходить // масштабирование растрового изображения var scaleMatrixiMatrix = new Matrix( ); matrix. scale(scaleFactor, scaleFactor);

// Переносим масштабированное растровое изображение

// в новый объект BitmapData

sealedBi tmapData. draw(ori gi nalBi tmapData, matri x);

// Заменяем исходный объект BitmapData. новым масштабированным объектом BitmapData originalBitmap. bitmapData = scaledBitmapData;

В следующем разделе мы узнаем более подробно о методе draw ( ).

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

Копирование графики в объект BitmapData

Значения цвета пикселов могут быть скопированы в объект BitmapData из двух источников: другого объекта BitmapData или любого экземпляра DisplayOb j ect.

Чтобы скопировать любой экземпляр класса Di splayOb j ect в объект BitmapData, мы применяем метод draw ( ), который копирует значения цвета из объекта-источника в объект-получатель BitmapData. В процессе копирования пикселы, сохраняемые в объекте BitmapData, могут быть преобразованы, смешаны или сглажены.

Чтобы скопировать значения цвета из другого объекта BitmapData, можно использовать либо метод draw ( ), либо любой из следующих методов класса BitmapData.

? copyPixels ( ) —копирует значения цвета из прямоугольной области пикселов объекта-источника BitmapData в объект-получатель BitmapData. Источ-

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

? copyChannel ( ) — копирует отдельный цветовой канал из прямоугольной области пикселов объекта-источника BitmapData в объект-получатель BitmapData. Источник и получатель могут являться одним объектом, позволяя копировать пикселы из одной области изображения в другую область того же изображения.

? clone ( ) —создает новый объект BitmapData, дублируя существующий объект BitmapData.

? merge ( ) — смешивает вместе каналы двух объектов BitmapData, создавая новое изображение, в котором одно изображение оказывается наложенным на другое. Объект-источник и объект-получатель BitmapData могут быть одним объектом, позволяя смешивать два канала одного и того же изображения.

В этом разделе мы сосредоточимся на методах draw ( ) ncopyPixels ( ). Дополнительную информацию о других методах копирования можно найти в описании класса BitmapData в справочнике по языку ActionScript корпорации Adobe.

Метод экземпляра draw() класса BitmapData

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

целевой0бъектВ1tmapData. йгам(источник, матрицаПреобразования, цветовыеПреобразования, режимСмешения, областьОбрезки, сглаживание)

Здесь целевойОбъектВ! tmapData — объект BitmapData, в который будут перенесены пикселы. Параметры метода draw ( ) описаны ниже.

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

? источник — экземпляр класса DisplayObject или BitmapData, графические данные которого будут перенесены в объект целевой0бъектВ1 tmapData. Это единственный обязательный параметр метода draw ( ). Стоит отметить, что, когда значением параметра источник является объект DisplayObject, при переносе в объект целевой0бъектВ1 tmapData его преобразования не включаются. Тем не менее преобразования объекта источник могут быть включены вручную путем передачи значения переменной источник. transform. matrix в качестве параметра матрицаПреобразований метода draw ( ), а значение переменной ^crovwM. transform. colorTransform — в качестве параметра цветовоеПреобразование метода draw ( ). В качестве альтернативы объект целевойОбъектВ! tmapData может быть связан с объектом BitmapData, переменная экземпляра transform которого ссылается на переменную источник. transform.

? матрицаПреобразования — необязательный объект Matrix, описывающий любое перемещение (то есть изменение позиции), масштабирование, вращение и искажение, которое должно быть применено к пикселам, переносимым в объект целевойОбъектВ! tmapData. Информацию об использовании объекта Matrix для выполнения графических преобразований можно найти в описании класса Matrix в справочнике по языку ActionScript корпорации Adobe и в разделе Programming ActionScript 3.0 > Flash Player APIs > Working With Geometry > Using Matrix objects документации корпорации Adobe. Общий пример матричных преобразований можно найти по адресу http://windowssdk. msdn. microsoft. com/en-us/library/ms536397.aspx и http://www. senocular. com/flash/tutorials/transformmatrix.

Стоит отметить, что гарантировать достаточный размер объекта целевойОбъ-ектЕН tmapData для хранения преобразованного объекта источник должен программист. В интерфейсе API приложения Flash Player 9 не предусмотрено никакой возможности для предварительного получения размера преобразованного объекта источник. Такая возможность может быть включена в будущие версии сред Flash, например, в виде метода generateTransf ormRect ( ) (разработанного после существующего метода generateFilterRect ( ) ). Чтобы отдать свой голос в поддержку подобного метода, посетите страницу http://www. adobe. com/ cfusion/mmform/index. cfm? name=wishform.

? цветовыеПреобразования — необязательный объект ColorTransf orm, описывающий любые цветовые изменения, которые должны быть применены к пикселам, переносимым в объект целевойОбьектВ1tmapData. Цветовые преобразования задаются независимо для каждого цветового канала либо с помощью множителя (числа, на которое умножается существующее значение цветового канала), либо с помощью смещения (числа, которое прибавляется к существующему значению цветового канала), либо с помощью обоих способов. Информацию по использованию объекта ColorTransf orm для выполнения графических преобразований можно найти в описании класса ColorTransformB справочнике по языку ActionScript корпорации Adobe.

? режимСмешения — необязательная константа класса В1 endMode, обозначающая тип смешения, который должен быть применен к пикселам, переносимым в объект целевойОбьектВ1tmapData. Смешение означает использование формул для объединения значений цвета объекта источник с отображаемыми объектами, которые визуально располагаются позади него, обычно с целью создания эффекта наложения. Поддерживаемыми режимами смешения являются BlendMode. MULTIPLY, BlendMode. SCREEN, BlendMode. HARDLIGHT и многие другие, которые знакомы пользователям программы Adobe Photoshop. Реализация режимов смешения в языке ActionScript основывается на стандарте SVG консорциума W3C (описание этого стандарта доступно по адресу http://www. w3.orgДR/2003/WD-SVG12-20030715/#compositing) и исследовании Дженса Грашела (Jens Gruschel), опубликованного по адресу http://www. pegtop. net/delphi/articles/blendmodes. Описание каждого доступного режима смешения и изображения, иллюстрирующие результаты применения этих режимов, можно найти в описании переменной экземпляра blendMode класса DisplayObject в справочнике по языку ActionScript корпорации Adobe.

? областьОбрезки — необязательный объект Rectangle, обозначающий прямоугольную область объекта целевойОбъектВ1 tmapData, в которую будут перенесены графические данные объекта источник.

? сглаживание — необязательный параметр типа Boolean, который обозначает, должно ли выполняться сглаживание растрового изображения во время рисования. Этот параметр оказывает влияние на результат только в том случае, когда объект источник является объектом BitmapData и указанный объект матрицаПреобразования задает параметры масштабирования или вращения. При этом, когда параметру сглаживание присвоено значение true, объект источник отображается в объекте целевойОбъектВ1 tmapData с использованием алгоритма сглаживания растровых изображений языка ActionScript. Когда параметру

сглаживание присвоено значение false, объект источник отображается в объекте целевойОбъектЕН tmapData без сглаживания. Изображение, выводимое с использованием сглаживания, выглядит менее «зазубренным» или «пикселизирован-ным», чем изображение, отображаемое без сглаживания. Это проиллюстрировано на рис. 26.6, где показано небольшое исходное изображение (вверху), которое увеличивается в три раза с помощью объекта Matrix с применением сглаживания (слева) и без применения сглаживания (справа).

Вывод на экран растрового изображения с применением сглаживания занимает больше времени, чем вывод без сглаживания. Чтобы достичь максимально возможной производительности, передавайте в качестве параметра сглаживание значение false; чтобы достичь максимально возможного качества изображения, передавайте в качестве параметра сглаживание значение true. Параметр сглаживание оказывает влияние только на текущую операцию draw ( ); он никак не влияет на применение сглаживания к объекту целевойОбьектВ! tmapData в дальнейшем.

Рис. 26.6. Сглаживание растрового изображения

Метод draw ( ) обычно применяется для:

? объединения нескольких отображаемых объектов в одно растровое изображение;

? растеризации векторного содержимого (то есть преобразования векторов в растровое изображение) с целью применения некоторого эффекта.



Полезные ссылки
Случайные записи
  • 10.07.2010">Дизайн сайта определяется контентом
  • 02.03.2011">Руководство по actionscript. часть 5, стр. 095
  • 27.02.2011">Руководство по actionscript. часть 6, стр. 036
  • 25.02.2011">Руководство по actionscript. часть 6, стр. 085
  • 11.03.2011">Руководство по actionscript. часть 4, стр. 013
  • 13.03.2011">Руководство по actionscript. часть 3, стр. 113
  • 14.03.2011">Руководство по actionscript. часть 3, стр. 081
  • 04.03.2011">Руководство по actionscript. часть 5, стр. 034
  • 10.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.55
  • 28.08.2011">Занимайся спортом стар и млад!
  • 15.06.2010">Самоучитель по креативному веб-дизайну. Книга 4, стр.41
  • 19.08.2013">Android с новыми возможностями на Chuwi V88
  • 03.06.2010">Самоучитель по креативному веб-дизайну. Книга 3, стр.83
  • 14.03.2011">Руководство по actionscript. часть 3, стр. 083
  • 07.03.2011">Руководство по actionscript. часть 4, стр. 107
Опрос

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

View Results

Loading ... Loading ...