سؤال

أقوم بتغيير قيم الألوان لكل بكسل في صورة بناءً على حساب. المشكلة هي أن هذا يستغرق أكثر من 5 ثوانٍ على الجهاز الخاص بي مع صورة 1000x1333 وأبحث عن وسيلة لتحسينها لتكون أسرع بكثير.

أظن ColorMatrix قد يكون خيارًا ، لكنني أواجه صعوبة في معرفة كيف سأحصل على مجموعة من قيم Pixel RGB ، واستخدم ذلك لحساب قيمة البيكسل الجديدة ثم ضبطها. أستطيع أن أرى كيف يمكن القيام بذلك إذا كنت فقط تعديل (مضاعفة ، طرح ، وما إلى ذلك) القيمة الأصلية مع Colormatrix ، ولكن الآن كيف يمكنني استخدام القيمة التي تم إرجاع البكسلات لاستخدامها للحساب والقيمة الجديدة.

علي سبيل المثال:

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

ال Luminance القيمة هي المحسوبة. أعلم أنه يمكنني ضبط ColorMatrix'S M00 ، M11 ، M22 إلى 0 ، 0 ، 0 على التوالي ، ثم وضع قيمة جديدة في M40 ، M41 ، M42 ، ولكن يتم حساب هذه القيمة الجديدة على أساس تكاثر القيمة وإضافة مكونات البكسل (((0.21 * (Clr.R) + (0.72 * (Clr.G)) + (0.07 * (Clr.B)) ونتيجة ذلك - Luminance - يتضاعف بواسطة مكون اللون).

هل هذا ممكن مع ColorMatrix?

هل كانت مفيدة؟

المحلول

لا. إن جعل أي واحد من مكونات اللون التي يتم ضربها مع نفسها أو أي مكون آخر غير ممكن مع colormatrix. يمكنك أن تضرب المكونات مع الثوابت ثم إضافة الأجزاء معًا.

لكن ماذا أنت تستطيع DO هو كتابة هذا إلى C# واستخدام .lockbits بدلاً من getPixel/setpixel. سيكون ذلك أسرع حتى ما يمكن أن تحققه مع colormatrix.

تحديث: بعض رمز العينة:

    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;
                }
            }
        }
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top