Вопрос: C# : Очень медленно работает код! | Добавлено: 04.09.10 11:05 |
Автор вопроса: ![]() |
В этом коде производится приращение значений r,g,b - по выбору(из ComboBox)
public partial class LavelsRGB : Form
{ Bitmap IMG = null; BitmapData BmpData = null; IntPtr PixPointer = IntPtr.Zero; byte[] MSV = null; const int Level_R = 0; const int Level_G = 1; const int Level_B = 2; int Step = 0; int _Width = 0; int _Height = 0; public LavelsRGB(Bitmap MainBitmap) { InitializeComponent(); if (MainBitmap == null) throw new ArgumentException(); else { IMG = MainBitmap; PreviewBox.Image = (Image)IMG; } switch (IMG.PixelFormat) { case PixelFormat.Alpha | PixelFormat.Format32bppArgb | PixelFormat.Format32bppPArgb: { Step = 4; break; } case PixelFormat.Format24bppRgb: { Step = 3; break; } default: { throw new ArgumentException("Неподходящий формат пикселей!"); break; } } _Width = IMG.Width; _Height = IMG.Height; } private void trackBar1_Scroll(object sender, EventArgs e) { textBox1.Text = trackBar1.Value.ToString(); int Color_Buffer = 0; if (IMG != null) { BmpData = IMG.LockBits(new Rectangle(0, 0, IMG.Width, IMG.Height), ImageLockMode.ReadWrite, IMG.PixelFormat); PixPointer = BmpData.Scan0; MSV = new byte[_Height * _Width * Step]; Marshal.Copy(PixPointer, MSV, 0, MSV.Length); switch (comboBox1.SelectedIndex) { case Level_R: { for (int AX = 0; AX < BmpData.Width; AX++) { for (int AY = 0; AY < BmpData.Height; AY++) { Color_Buffer = MSV[((AY * _Width + AX) * Step) + 2]; if ((Color_Buffer != 255) && (Color_Buffer > 0)) { if (Color_Buffer + trackBar1.Value > 255) MSV[((AY * _Width + AX) * Step) + 2] = 255; else if (Color_Buffer + trackBar1.Value < 0) MSV[((AY * _Width + AX) * Step) + 2] = 1; else MSV[((AY * _Width + AX) * Step) + 2] += Convert.ToByte(trackBar1.Value); } } } break; } case Level_G: { for (int AX = 0; AX < BmpData.Width; AX++) { for (int AY = 0; AY < BmpData.Height; AY++) { Color_Buffer = MSV[((AY * _Width + AX) * Step) + 1]; if ((Color_Buffer != 255) && (Color_Buffer > 0)) { if (Color_Buffer + trackBar1.Value > 255) MSV[((AY * _Width + AX) * Step) + 1] = 255; else if (Color_Buffer + trackBar1.Value < 0) MSV[((AY * _Width + AX) * Step) + 1] = 1; else MSV[((AY * _Width + AX) * Step) + 1] += Convert.ToByte(trackBar1.Value); } } } break; } case Level_B: { for (int AX = 0; AX < BmpData.Width; AX++) { for (int AY = 0; AY < BmpData.Height; AY++) { Color_Buffer = MSV[((AY * _Width + AX) * Step) + 0]; if ((Color_Buffer != 255) && (Color_Buffer > 0)) { if (Color_Buffer + trackBar1.Value > 255) MSV[((AY * _Width + AX) * Step) + 0] = 255; else if (Color_Buffer + trackBar1.Value < 0) MSV[((AY * _Width + AX) * Step) + 0] = 1; else MSV[((AY * _Width + AX) * Step) + 0] += Convert.ToByte(trackBar1.Value); } } } break; } } Marshal.Copy(MSV, 0, PixPointer, MSV.Length); IMG.UnlockBits(BmpData); PreviewBox.Image = (Image)IMG; } } } Он обробатывает изображение 1024x768 24bpp за 20сек(наверно даже медленнее чем Get/Set Pixel). В статьях написано что через Lock/Unlock Bits работает быстро, а на деле - 20сек.Это так и должно быть или я коряво написал? |
Ответы | Всего ответов: 41 |
Номер ответа: 1 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() Вопросов: 80 Ответов: 476 |
Профиль | Цитата | #1 | Добавлено: 04.09.10 11:42 |
А ты посчитай. 1024*768 = 786432 раза будет проходить твой цикл. Притом каждый раз будет грузится по 24бита информации о цвете. |
Номер ответа: 2 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Вопросов: 20 Ответов: 79 |
Web-сайт: Профиль | Цитата | #2 | Добавлено: 04.09.10 13:09 |
А как от этого избавиться? |
Номер ответа: 3 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 58 Ответов: 4255 ![]() |
Профиль | Цитата | #3 | Добавлено: 04.09.10 14:33 |
Это так и должно быть или я коряво написал?
Это ты коряво написал... Зачем тебе циклы по AX и AY? Ширина и высота тут роли не играют.. У тебя есть массив байт в который ты скопировал данные о цвете(MSV).. вот с ним и работай! Там должен быть 1 цикл по этому массиву.. В зависимости от формата обрабатываешь каждый 3 или 4 байт этого массива и все.. А ты по стопиццот раз прокручиваешь все это в циклах.. Там есть одно НО! Байты расположены в обратном порядке.. т.е. BGRA и BGR соответственно.. Это значит, что твой цикл должен начинаться с позиции байта нужного цвета и шаг приращения тоже будет разным в зависимости от формата(3 или 4). И за 1 проход цикла ты изменишь нужный канал.. Если все верно сделаешь то код будет работать сотые доли секунды.. Надеюсь, объяснил достаточно понятно.. |
Номер ответа: 4 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Вопросов: 20 Ответов: 79 |
Web-сайт: Профиль | Цитата | #4 | Добавлено: 04.09.10 15:56 |
А на примере можешь показать? |
Номер ответа: 5 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 58 Ответов: 4255 ![]() |
Профиль | Цитата | #5 | Добавлено: 04.09.10 16:27 |
лениво.. |
Номер ответа: 6 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Вопросов: 20 Ответов: 79 |
Web-сайт: Профиль | Цитата | #6 | Добавлено: 04.09.10 17:25 |
Напиши пожалуйста... |
Номер ответа: 7 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 58 Ответов: 4255 ![]() |
Профиль | Цитата | #7 | Добавлено: 04.09.10 18:10 |
В общем случае это должно выглядеть примерно так:
Пример использования (тестовый проект C# FW 3.5) выложил тут: http://clip2net.com/s/w2v5 |
Номер ответа: 8 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 58 Ответов: 4255 ![]() |
Профиль | Цитата | #8 | Добавлено: 04.09.10 18:27 |
тут косяк форума.. переменную i в квадратных скобках он расценил как тег форматирования.. поэтому код бери из исходников.. |
Номер ответа: 9 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Вопросов: 20 Ответов: 79 |
Web-сайт: Профиль | Цитата | #9 | Добавлено: 04.09.10 23:41 |
Огромное спасибо! |
Номер ответа: 10 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 58 Ответов: 4255 ![]() |
Профиль | Цитата | #10 | Добавлено: 05.09.10 09:03 |
Тут львиная доля времени тратится на копирование куска памяти в массив байт и обратно, и в идеале, этот код можно еще ускорить. Поскольку мы имеем указатель на первый байт картинки в памяти(Scan0) то, заюзав unsafe mode + указатель, можно ничего не копируя модифицировать данные о цвете напрямую в памяти. Но для этого ты должен быть знаком с С++ и указателями.. |
Номер ответа: 11 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Вопросов: 20 Ответов: 79 |
Web-сайт: Профиль | Цитата | #11 | Добавлено: 06.09.10 18:46 |
Сделал так как ты сказал,но вот что он делает(в исходнике всё работает нормльно,а у меня...) - http://www.supersait16.ucoz.ru/FTP/snimok.jpg
|
Номер ответа: 12 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Вопросов: 20 Ответов: 79 |
Web-сайт: Профиль | Цитата | #12 | Добавлено: 06.09.10 18:47 |
В чём проблема? |
Номер ответа: 13 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 58 Ответов: 4255 ![]() |
Профиль | Цитата | #13 | Добавлено: 06.09.10 19:02 |
В чём проблема?
в руках... |
Номер ответа: 14 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Вопросов: 20 Ответов: 79 |
Web-сайт: Профиль | Цитата | #14 | Добавлено: 06.09.10 19:21 |
Наверно,что я не правильно написал? ...проверил-вроде так как надо |
Номер ответа: 15 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 58 Ответов: 4255 ![]() |
Профиль | Цитата | #15 | Добавлено: 06.09.10 19:29 |
Дружище, без обид - включай моцк.. Я потратил время, чтоб написать для тебя рабочий пример, а ты не желаешь потратить время чтоб найти косяк в своем коде? |
|