在C#中实现颜色过滤

时间:2010-03-04 04:34:06

标签: c# gdi+

我正在尝试在我的应用程序中实现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;
                ...
                ...
            }
        }

然后是通常的Marshal.Copy和解锁位等......

正如你所看到的,它并不是一种真正的优化方式,我想要一些更快的方法的建议。

由于

1 个答案:

答案 0 :(得分:0)

目前还不清楚你想对个人r,g,b&amp;一个值,但我看到的一件事就是你可以将你的启用标志移出循环。

   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&amp;一个值。

   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的数组很有帮助,只需调整偏移量并跨越数据就可以更轻松地选择各个颜色通道