Question

Je change les valeurs de couleur de chaque pixel dans une image basée sur un calcul. Le problème est que cela prend plus de 5 secondes sur ma machine avec une image 1000x1333 et je suis à la recherche d'une façon d'optimiser à être beaucoup plus rapide.

Je pense que ColorMatrix peut être une option, mais je vais avoir un chiffre moment difficile comment je recevrais un ensemble de pixels valeurs RVB, utiliser pour calculer et définir la nouvelle valeur de pixel. Je peux voir comment cela peut se faire que si je ne faisais que de modification (multiplication, soustraction, etc.) la valeur originale avec ColorMatrix, mais maintenant comment je peux utiliser les pixels retournés valeur à utiliser pour calculer et nouvelle valeur.

Par exemple:

Sub DarkenPicture()
    Dim clrTestFolderPath = "C:\Users\Me\Desktop\ColorTest\"
    Dim originalPicture = "original.jpg"
    Dim Luminance As Single
    Dim bitmapOriginal As Bitmap = Image.FromFile(clrTestFolderPath + originalPicture)
    Dim Clr As Color
    Dim newR As Byte
    Dim newG As Byte
    Dim newB As Byte
    For x = 0 To bitmapOriginal.Width - 1
        For y = 0 To bitmapOriginal.Height - 1
            Clr = bitmapOriginal.GetPixel(x, y)
            Luminance = ((0.21 * (Clr.R) + (0.72 * (Clr.G)) + (0.07 * (Clr.B))/ 255
            newR = Clr.R * Luminance
            newG = Clr.G * Luminance
            newB = Clr.B * Luminance
            bitmapOriginal.SetPixel(x, y, Color.FromArgb(newR, newG, newB))
        Next
    Next
    bitmapOriginal.Save(clrTestFolderPath + "colorized.jpg", ImageFormat.Jpeg)
End Sub

La valeur de Luminance est celui calculé. Je sais que je peux mettre M00, M11, M22 à 0 de ColorMatrix, 0, 0, respectivement, et puis mettre une nouvelle valeur dans M40, M41, M42, mais cette nouvelle valeur est calculée à partir d'une multiplication de la valeur et l'ajout de (((0.21 * (Clr.R) + (0.72 * (Clr.G)) + (0.07 * (Clr.B)) composants de ce pixel et le résultat de cette - Luminance -. est multipliée par la composante de couleur)

Est-ce même possible avec ColorMatrix?

Était-ce utile?

La solution

Non

. Faire une quelconque des composantes de couleur étant multipliée par elle-même ou tout autre composant est pas possible avec un ColorMatrix. Vous pouvez ony multiplier les composants avec des constantes, puis ajoutez les pièces ensemble.

Mais ce que vous peut faire est d'écrire cela en C # et l'utilisation .LockBits au lieu de GetPixel / SetPixel. Ce serait encore plus rapide que ce que vous pourriez obtenir avec un ColorMatrix.

UPDATE : un exemple de code:

    private static void myVerySpecialSepia(
        IntPtr source,
        IntPtr destination,
        int height,
        int width,
        int sourceStride,
        int destinationStride,
        int sourceBytesPerPixel,
        int destinationBytesPerPixel )
    {
        unsafe
        {
            for ( int y = 0 ; y < height ; y++ )
            {
                byte* pOrig = (byte*)source.ToPointer() + sourceStride * y;
                byte* pDest = (byte*)destination.ToPointer() + destinationStride * y;
                for ( int x = width ; x > 0 ; x-- )
                {
                    float b = pOrig[0];
                    float g = pOrig[1];
                    float r = pOrig[2];
                    float b2 = b * b;
                    float g2 = g * g;
                    float r2 = r * r;
                    pDest[0] = (byte)(
                        b * 0.400367618f + b2 * 0.00011502471f +
                        g * (-0.0337239578f) + g2 * 0.00056673412f +
                        r * 0.221445322f + r2 * 0.0008506606f +
                        6.2766808485f);
                    pDest[1] = (byte)(
                        b * 0.493460029f + b2 * (-0.00023297003f) +
                        g * (-0.008577178f) + g2 * 0.00031247039f +
                        r * 0.5043012 + r2 * (-0.00006892065f) +
                        0.2746957206f);
                    pDest[2] = (byte)(
                        b * 0.617727f + b2 * (-0.00070876251f) +
                        g * 0.00271902746f + g2 * 0.00007401942f +
                        r * 0.6954346f + r2 * (-0.00065937551f) +
                        0.116103285f);
                    pOrig += sourceBytesPerPixel;
                    pDest += destinationBytesPerPixel;
                }
            }
        }
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top