Реализация цветовой фильтрации в C # - PullRequest
1 голос
/ 04 марта 2010

Я пытаюсь реализовать функцию цветовой фильтрации в стиле Photoshop в моем приложении. У меня есть растровое изображение и 4 флажка (R, G, B, A). Я хотел знать, какой самый быстрый способ сделать это

В настоящее время я делаю это следующим образом

        Byte[] rgbValues = new Byte[data.Stride * data.Height];
        for (int row = 0; row < data.Height; row++)
        {
            // Loop through each pixel on this scan line
            int bufPos = (m_height - row - 1) * m_width;
            int index = row * data.Stride;
            for (int col = 0; col < data.Width; col++, bufPos++, index += 4)
            {
                bool drawCheckerBoard = true; // for alpha
                UInt32 rgba = m_image[bufPos];
                UInt32 r =  EnableRedChannel ? ((rgba >> 0) & 0xFF) : 0x00;
                UInt32 g =  EnableGreenChannel ? ((rgba >> 8) & 0xFF) : 0x00;
                UInt32 b =  EnableBlueChannel ? ((rgba >> 16) & 0xFF) : 0x00;
                UInt32 a = (rgba >> 24) & 0xFF;
                ...
                ...
            }
        }

а потом обычный маршал. Копируй и разблокируй биты и т.д ...

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

Спасибо

1 Ответ

0 голосов
/ 04 марта 2010

Неясно, что вы хотите сделать с отдельными значениями r, g, b & a, но я сразу вижу, что вы можете вывести флаги включения из цикла.

   UInt32 rMask = EnableRedChannel   ? 0x000000FF : 00;
   UInt32 gMask = EnableGreenChannel ? 0x0000FF00 : 00;
   UInt32 bMask = EnableBlueChannel  ? 0x00FF0000 : 00;
   UInt32 aMask = 0xFF000000;

   for (int row = 0; row < data.Height; row++)
    {
        // Loop through each pixel on this scan line
        int bufPos = (m_height - row - 1) * m_width;
        int index = row * data.Stride;
        for (int col = 0; col < data.Width; col++, bufPos++, index += 4)
        {
            bool drawCheckerBoard = true; // for alpha
            UInt32 rgba = m_image[bufPos];
            UInt32 r =  (rgba & aMask) >> 0;
            UInt32 g =  (rgba & gMask) >> 8;
            UInt32 b =  (rgba & bMask) >> 16;
            UInt32 a =  (rgba & aMask) >> 24;
            ...
            ...
        }
    }

Пройдя еще один шаг, вы можете создать составную маску, если вам не нужно извлекать значения r, g, b & a.

   UInt32 mask  = 0xFF000000;
   if (EnableRedChannel)
      mask |= 0x000000FF;
   if (EnableGreenChannel)
      mask |= 0x0000FF00;
   if (EnableBlueChannel)
      mask |= 0x00FF0000;

   for (int row = 0; row < data.Height; row++)
    {
        // Loop through each pixel on this scan line
        int bufPos = (m_height - row - 1) * m_width;
        int index = row * data.Stride;
        for (int col = 0; col < data.Width; col++, bufPos++, index += 4)
        {
            bool drawCheckerBoard = true; // for alpha
            UInt32 rgba = m_image[bufPos] & mask;
            ...
            ...
        }
    }

Вам также может быть полезно, чтобы ваш m_image [] был массивом byte s, это облегчит выбор отдельных цветовых каналов, просто отрегулировав смещение и пройдя по данным.

...