كيفية استخدام قيم الألوان المحسوبة مع colormatrix؟
-
26-09-2019 - |
سؤال
أقوم بتغيير قيم الألوان لكل بكسل في صورة بناءً على حساب. المشكلة هي أن هذا يستغرق أكثر من 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;
}
}
}
}