Страница: 1 |
Страница: 1 |
Вопрос: Производительность
Добавлено: 03.11.10 19:03
Автор вопроса: Лёха | Web-сайт:
Выполняю гаюсово размытие с помощью такого еода :
{
Bitmap Origin_IMG = (Bitmap)Main.Clone();
Bitmap Blurred_IMG = new Bitmap(Main.Width, Main.Height);
using (RawBitmap SRC = new RawBitmap(Origin_IMG))
{
using (RawBitmap DEST = new RawBitmap(Blurred_IMG))
{
int PixelCount = SRC.Width * SRC.Height;
int[] CL_B = new int[PixelCount];
int[] CL_G = new int[PixelCount];
int[] CL_R = new int[PixelCount];
int[] CL_B2 = new int[PixelCount];
int[] CL_G2 = new int[PixelCount];
int[] CL_R2 = new int[PixelCount];
int Offset = SRC.GetOffset();
int Index = 0;
unsafe
{
byte* Ptr = SRC.Begin;
for (int I = 0; I < SRC.Height; I++)
{
for (int G = 0; G < SRC.Width; G++)
{
CL_B[Index] = *Ptr;
Ptr++;
CL_G[Index] = *Ptr;
Ptr++;
CL_R[Index] = *Ptr;
Ptr++;
++Index;
}
Ptr += Offset;
}
int CL_B_Sum;
int CL_G_Sum;
int CL_R_Sum;
int Read;
int Start = 0;
Index = 0;
for (int I = 0; I < SRC.Height; I++)
{
for (int J = 0; J < SRC.Width; J++)
{
CL_B_Sum = CL_G_Sum = CL_R_Sum = 0;
Read = Index - BlurRadius;
for (int Z = 0; Z < BlurKernel.Length; Z++)
{
if (Read < Start)
{
CL_B_Sum += Multable[Z, CL_B[Start]];
CL_G_Sum += Multable[Z, CL_G[Start]];
CL_R_Sum += Multable[Z, CL_R[Start]];
}
else if (Read > Start + SRC.Width - 1)
{
int IDX = Start + SRC.Width - 1;
CL_B_Sum += Multable[Z, CL_B[IDX]];
CL_G_Sum += Multable[Z, CL_G[IDX]];
CL_R_Sum += Multable[Z, CL_R[IDX]];
}
else
{
CL_B_Sum += Multable[Z, CL_B[Read]];
CL_G_Sum += Multable[Z, CL_G[Read]];
CL_R_Sum += Multable[Z, CL_R[Read]];
}
++Read;
}
CL_B2[Index] = (CL_B_Sum / KernelSum);
CL_G2[Index] = (CL_G_Sum / KernelSum);
CL_R2[Index] = (CL_R_Sum / KernelSum);
++Index;
}
Start += SRC.Width;
}
int Temp_Y;
for (int I = 0; I < SRC.Height; I++)
{
int Y = I - BlurRadius;
Start = Y * SRC.Width;
for (int J = 0; J < SRC.Width; J++)
{
CL_B_Sum = CL_G_Sum = CL_R_Sum = 0;
Read = Start + J;
Temp_Y = Y;
for (int Z = 0; Z < BlurKernel.Length; Z++)
{
if (Temp_Y < 0)
{
CL_B_Sum += Multable[Z, CL_B2[J]];
CL_G_Sum += Multable[Z, CL_G2[J]];
CL_R_Sum += Multable[Z, CL_R2[J]];
}
else if (Temp_Y > SRC.Height - 1)
{
int IDX = PixelCount - (SRC.Width - J);
CL_B_Sum += Multable[Z, CL_B2[IDX]];
CL_G_Sum += Multable[Z, CL_G2[IDX]];
CL_R_Sum += Multable[Z, CL_R2[IDX]];
}
else
{
CL_B_Sum += Multable[Z, CL_B2[Read]];
CL_G_Sum += Multable[Z, CL_G2[Read]];
CL_R_Sum += Multable[Z, CL_R2[Read]];
Read += SRC.Width;
++Temp_Y;
}
byte* PCell = DEST[J, I];
PCell[0] = (byte)(CL_B_Sum / KernelSum);
PCell[1] = (byte)(CL_G_Sum / KernelSum);
PCell[2] = (byte)(CL_R_Sum / KernelSum);
}
}
}
}
}
Размытие радиусом в 20 выполняется 10.5 сек,как сделать быстрее?
В Paint.Net оно же выполняется 2.5 секунды!
return Blurred_IMG;
}
Ответы
Всего ответов: 3
Номер ответа: 1
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #1
Добавлено: 03.11.10 22:43
Доставать пиксели из картинки квадратиками в массив, чтобы избежать кэш-промахов, юзать интринсики для векторной обработки, не делать лишние копирования битмапов. Как вариант: почитать сырцы Paint.NET.
Номер ответа: 2
Автор ответа:
Лёха
Вопросов: 20
Ответов: 79
Web-сайт:
Профиль | | #2
Добавлено: 04.11.10 09:52
Что такое кэш-промахи?
Номер ответа: 3
Автор ответа:
AgentFire
ICQ: 192496851
Вопросов: 75
Ответов: 3178
Профиль | | #3
Добавлено: 04.11.10 12:49
http://lmgtfy.com/?q=%D0%BA%D1%8D%D1%88-%D0%BF%D1%80%D0%BE%D0%BC%D0%B0%D1%85
первые две ссылки, как ни странно, дают ответ на твой вопрос