Как быстро объединить два массива image byte [] вместе с использованием массива масок в C # - PullRequest
0 голосов
/ 29 июля 2011

В двух словах у меня есть два изображения, которые я хочу наложить одно поверх другого, используя маску, чтобы отображались только части второго изображения.Это часть процедуры обработки изображения в реальном времени, поэтому мне нужно, чтобы операция выполнялась как можно быстрее.

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

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

Какой самый быстрый способ сделатьthis?

Я просматривал статью в Википедии о старомодной маскировке спрайтов, но я не уверен, как лучше всего перевести это на C #.http://en.wikipedia.org/wiki/Mask_(computing)

РЕДАКТИРОВАТЬ: я забыл упомянуть, что я могу изменить все или все это, чтобы он работал быстрее.

Ответы [ 4 ]

0 голосов
/ 29 июля 2011

Возможно, я неправильно понял вопрос, но: у вас есть два массива int и массив масок одинакового размера, который применяет соответствующую маску к обоим массивам изображений.Где бит в массиве маски равен 0, вы выбираете бит из A;когда 1, вы выбираете бит из b.

Так, если, например, у вас были значения в первом элементе массива:

 a[0]    : 0000 1111
 b[0]    : 0011 0011
 mask[0] : 0101 0101

Тогда конечный результат будет:

 dest[i] : 0001 1011

Это может быть выражено как:

dest[i] = (a[i] AND (NOT MASK[i]))
          OR
          (b[i] AND MASK[i])

Или в C #:

dest[i] = (a[i] & ~mask[i]) | (b[i] & mask[i]);

Если это намерение, то вы можете просто запустить как цикл:

for (int i = 0; i < len; i++)
{
    dest[i] = (a[i] & ~mask[i]) | (b[i] & mask[i]); 
}

Наконец, с точки зрения производительности, одно замечание: вы упомянули о создании нового массива для хранения целевого изображения.Если изображения имеют значительный размер, постоянное создание больших массивов может стать узким местом.Вместо этого, если возможно, создайте целевой массив один раз и используйте его по мере необходимости.Кроме того, если вам нужно выделить большое количество байтовых массивов для временного использования (например, внутри метода), вы можете рассмотреть возможность использования оператора stackalloc для выделения пространства в стеке, что может быть более эффективным, чем создание новых управляемых массивов..

0 голосов
/ 29 июля 2011

Сторонние инструменты - это путь. Я использовал Lead Tools, но есть много других.

Если вы хотите сделать это самостоятельно, вы можете использовать метод LockBits.

Лучшая демонстрация LockBits здесь: http://www.bobpowell.net/lockingbits.htm, но ссылка в настоящее время не работает. Надеюсь, мистер Пауэлл исправит это.

0 голосов
/ 29 июля 2011

В принципе, маскировка, подобная этой, очень проста - при условии, что массивы имеют одинаковый размер, этот код сделает это:

static void MaskImage(byte[] background, byte[] foreground, byte[] mask)
{
    for (var i = 0; i < background.Length; ++i)
    {
        background[i] &= mask[i];
        background[i] |= foreground[i];
    }
}

В реальности это будет немного сложнее - ваш фонвероятно, будет больше, чем любое изображение на переднем плане, которое вы маскируете, и вам нужно будет сделать некоторую арифметику, чтобы правильно разместить его.Хотя это утомительно, но не сложно.

0 голосов
/ 29 июля 2011

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

http://pastebin.com/KXavA9Jr

...