Как работает DisplacementMapFilter? - PullRequest
6 голосов
/ 14 марта 2012

Я новичок в ActionScript.Если я правильно понимаю, DisplacementMapFilter перемещает пиксели из «исходного изображения» в соответствии с цветом соответствующей позиции пикселя в «изображении MAP».

Проблема заключается в том, что мое конечное изображение содержит пиксели, которые НЕ находятся висходное изображение!

Например, я беру «исходное изображение» UNICOLOR 10 * 10 пикселей с данными BitMapData:

sourceBitmap = new BitmapData(BITMAP_WIDTH, BITMAP_HEIGHT, false, 0x000002);

produce:

  0   1   2   3   4   5   6   7   8   9
[002,002,002,002,002,002,002,002,002,002] Row 0
[002,002,002,002,002,002,002,002,002,002] Row 1
[002,002,002,002,002,002,002,002,002,002] Row 2
[002,002,002,002,002,002,002,002,002,002] Row 3
[002,002,002,002,002,002,002,002,002,002] Row 4
[002,002,002,002,002,002,002,002,002,002] Row 5
[002,002,002,002,002,002,002,002,002,002] Row 6
[002,002,002,002,002,002,002,002,002,002] Row 7
[002,002,002,002,002,002,002,002,002,002] Row 8
[002,002,002,002,002,002,002,002,002,002] Row 9

Теперь я беру эту ЧЕРНУЮ карту смещения и добавляюмаленький СИНИЙ квадрат:

displacementBitmap = new BitmapData(BITMAP_WIDTH,BITMAP_HEIGHT,false,0x000000);
for(i=5;i<10;i++)
    for(j=5;j<10;j++)
        displacementBitmap.setPixel(i,j,255);

produce:

 0   1   2   3   4   5   6   7   8   9 
[000,000,000,000,000,000,000,000,000,000] Row 0
[000,000,000,000,000,000,000,000,000,000] Row 1
[000,000,000,000,000,000,000,000,000,000] Row 2
[000,000,000,000,000,000,000,000,000,000] Row 3
[000,000,000,000,000,000,000,000,000,000] Row 4
[000,000,000,000,000,255,255,255,255,255] Row 5
[000,000,000,000,000,255,255,255,255,255] Row 6
[000,000,000,000,000,255,255,255,255,255] Row 7
[000,000,000,000,000,255,255,255,255,255] Row 8
[000,000,000,000,000,255,255,255,255,255] Row 9

Результат:

displacementFilter = new DisplacementMapFilter();
displacementFilter.alpha=0;
displacementFilter.color=0;
displacementFilter.mapPoint=new Point(0,0);
displacementFilter.scaleX=1;
displacementFilter.scaleY=1;
displacementFilter.componentX = flash.display.BitmapDataChannel.BLUE;
displacementFilter.componentY = flash.display.BitmapDataChannel.BLUE;
displacementFilter.mapBitmap = displacementBitmap;

destinationBitmap = new BitmapData(BITMAP_WIDTH,BITMAP_HEIGHT,false,0xFFFFFFFF);
destinationBitmap.applyFilter(
    sourceBitmap.bitmapData,
    new Rectangle(0,0,BITMAP_WIDTH,BITMAP_HEIGHT),
    new Point(0,0),
    displacementFilter
);

produce:        

  0   1   2   3   4   5   6   7   8   9 
[002,002,002,002,002,002,002,002,002,002] Row 0
[002,002,002,002,002,002,002,002,002,002] Row 1
[002,002,002,002,002,002,002,002,002,002] Row 2
[002,002,002,002,002,002,002,002,002,002] Row 3
[002,002,002,002,002,002,002,002,002,002] Row 4
[002,002,002,002,002,001,001,001,001,001] Row 5
[002,002,002,002,002,001,001,001,001,001] Row 6
[002,002,002,002,002,001,001,001,001,001] Row 7
[002,002,002,002,002,001,001,001,001,001] Row 8
[002,002,002,002,002,001,001,001,001,001] Row 9

Так что я не понимаю, почему у меня есть пиксели '001', которых нет в исходном изображении.

Большое спасибо.

1 Ответ

3 голосов
/ 07 апреля 2012

Фильтр карты смещения решает, какой пиксель извлечь из исходного растрового изображения, используя эту формулу :

dstPixel[x, y] = srcPixel[x + ((componentX(x, y) - 128) * scaleX) / 256, y + ((componentY(x, y) - 128) *scaleY) / 256)

dstPixel - это битовая карта назначения, srcPixel - это битовая карта источника, а componentX/Y - из битовой карты смещения. Отображение определяется тем, насколько далеко компонентный канал находится от 128. Обратите внимание, что 128 - это нейтральное значение, где нет преобразования, и используется тот же исходный пиксель.

Например, давайте рассмотрим пиксель в (1, 1) в вашем случае. Ваш компонентный канал имеет синий цвет, а синий канал в точке (1, 1) на карте смещения имеет значение 0. Поэтому мы смещаемся на (0 - 128) / 256 или -0,5. Таким образом, последний пиксель, который мы получаем из исходного растрового изображения, равен (0,5, 0,5).

Но что значит использовать половину пикселя? Оказывается, что Flash использует билинейную фильтрацию , чтобы сгладить результаты. В итоге получается сочетание цветов в четырех пикселях между (0,0) и (1,1).

По этой причине вы видите нечетные пиксели, которых нет в исходном изображении. Несмотря на то, что все пиксели в исходном изображении имеют один и тот же цвет, кажется, что при интерполяции между цветами Flash имеет некоторые неточности с плавающей запятой, поэтому иногда вы получаете значение, которое просто слегка . Обратите внимание, что если вы используете значение в вашем растровом изображении смещения, которое делится «чисто» на 128, например 0 или 64, то вы получите правильный результат. Но если вы используете значение, например 255 или 19, вы получите ошибку.

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

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

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