Pergunta

Estou alterando os valores de cores de cada pixel em uma imagem com base em um cálculo. O problema é que isso leva mais de 5 segundos na minha máquina com uma imagem de 1000x1333 e estou procurando uma maneira de otimizá -la para ser muito mais rápida.

Eu penso ColorMatrix Pode ser uma opção, mas estou tendo dificuldades para descobrir como obteria um conjunto de valores de Pixel RGB, use isso para calcular e definir o novo valor de pixel. Eu posso ver como isso pode ser feito se eu estivesse apenas modificando (multiplicando, subtraindo etc.) o valor original com o Colormatrix, mas agora como posso usar o valor retornado dos pixels para usá -lo para calcular e novo valor.

Por exemplo:

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

o Luminance O valor é o calculado. Eu sei que posso definir ColorMatrixM00, M11, M22 a 0, 0, 0, respectivamente, e depois coloque um novo valor em M40, M41, M42, mas esse novo valor é calculado com base em uma multiplicação de valor e adição dos componentes desse pixel (((0.21 * (Clr.R) + (0.72 * (Clr.G)) + (0.07 * (Clr.B)) e o resultado disso - Luminance - é multiplicado pelo componente de cores).

Isso é possível com ColorMatrix?

Foi útil?

Solução

Não. Tornar qualquer um dos componentes de cores que estão sendo multiplicados consigo mesmo ou qualquer outro componente não é possível com uma Colormatrix. Você pode multiplicar os componentes com constantes e depois adicionar as peças.

Mas o que você posso Faça é escrever isso no C# e usar .lockbits em vez de getpixel/setPixel. Isso seria ainda mais rápido que o que você poderia alcançar com uma Colormatrix.

ATUALIZAR: Algum código de amostra:

    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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top