Pregunta

Estoy cambiando los valores de color de cada píxel de una imagen basada en un cálculo. El problema es que esto toma más de 5 segundos en mi máquina con una imagen de 1000x1333 y estoy buscando una manera de optimizar que sea mucho más rápido.

Creo ColorMatrix puede ser una opción, pero estoy teniendo una figura difícil momento cómo me gustaría tener un conjunto de valores RGB de píxeles, el uso que para calcular y establecer el nuevo valor de píxel. Puedo ver cómo esto se puede hacer si sólo estaba modificando (multiplicar, restar, etc.) el valor original con ColorMatrix, pero ahora cómo puedo usar los píxeles devueltos valor a utilizar para calcular y nuevo valor.

Por ejemplo:

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

El valor Luminance es la calculada. Sé que puedo fijar de ColorMatrix M00, M11, M22 a 0, 0, 0, respectivamente, y luego poner un nuevo valor en M40, M41, M42, pero que el nuevo valor se calcula a partir de una multiplicación valor y la adición de los componentes de ese píxel (((0.21 * (Clr.R) + (0.72 * (Clr.G)) + (0.07 * (Clr.B)) y el resultado de que - Luminance -. se multiplica por el componente de color)

Es esto posible con ColorMatrix?

¿Fue útil?

Solución

No. Hacer cualquiera de los componentes de color se multiplica por sí mismo o cualquier otro componente no es posible con un ColorMatrix. Puede ony multiplican los componentes con constantes y luego añadir las piezas juntas.

Pero lo que puede hacer es escribir esto en C # y uso .LockBits en lugar de GetPixel / SetPixel. Eso sería aún más rápido que lo que lo que pueda lograr con un ColorMatrix.

Actualizar : un código de ejemplo:

    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;
                }
            }
        }
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top