2010-03-04 3 views
1

J'essaie d'implémenter une fonction de filtrage des couleurs de style Photoshop dans mon application. J'ai un bitmap, et 4 cases à cocher (R, G, B, A). Je voulais savoir ce qui est le meilleur moyen de le faireImplémentation du filtrage des couleurs en C#

Actuellement, je fais comme suit

 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; 
       ... 
       ... 
      } 
     } 

puis la Marshal.Copy habituelle et débloquer les bits etc ...

Comme vous peut voir ce n'est pas vraiment un moyen optimisé, je voulais des suggestions pour une méthode plus rapide.

Merci

+0

Est-ce que c'est vraiment lent? –

Répondre

0

On ne sait pas ce que vous voulez faire avec la r personne, g, b & une valeur, mais une chose que je vois droit est ce que vous pouvez déplacer vos drapeaux permettent de la boucle.

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; 
      ... 
      ... 
     } 
    } 

Franchir une étape au-delà, vous pouvez construire un masque composite si vous n'avez pas vraiment besoin de tirer le r, g, b & a des valeurs.

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; 
      ... 
      ... 
     } 
    } 

Vous trouverez peut-être aussi utile d'avoir votre de votre m_image [] être un tableau de byte s, ce serait plus facile de choisir les canaux de couleur tout en ajustant votre décalage et foulée par les données .

+0

Merci .. Je vais essayer ça ... – ababeel