Страница: 1 | 2 |
|
Вопрос: Оптимизировать, но как?
|
Добавлено: 12.05.05 22:09
|
|
Автор вопроса: SyavX
|
Hello, World!
Вопрос знающим от незнающего:
Как можно оптимизировать этот код?
Sub SetRgnMask Alias "SetRgnMask" (ByVal hWndDest As Long, ByVal hWndSrc As Long, ByVal hDCSrc As Long, ByVal lMaskColor As Long) Export
Dim CurRgn As Long, TempRgn As Long
Dim WndRect As RECT, Result As Long
Dim lHeight As Long, lWidth As Long
Dim X As Long, Y As Long
Result = GetWindowRect(hWndSrc, WndRect)
lHeight = WndRect.nBottom - WndRect.nTop
lWidth = WndRect.nRight - WndRect.nLeft
CurRgn = CreateRectRgn(0, 0, lWidth, lHeight)
Do While Y <= lHeight
Do While X <= lWidth
If GetPixel(hDCSrc, X, Y) = lMaskColor Then
TempRgn = CreateRectRgn(X, Y, X + 1, Y + 1)
Result = CombineRgn(CurRgn, CurRgn, TempRgn, %RGN_DIFF)
Result = DeleteObject(TempRgn)
End If
X = X + 1
Loop
Y = Y + 1
X = 0
Loop
Result = SetWindowRgn(hWndDest, CurRgn, %True)
Result = DeleteObject(CurRgn)
Result = DeleteObject(TempRgn)
End Sub
Если использовать его через BP'шную DLL, он выполняется быстрей чем посто в VB, но разница не большая (~ 3/4). Возможно просто есть другое решение этой задачи (создание региона по маске) ?
Ответить
|
Номер ответа: 3 Автор ответа: HOOLIGAN
Вопросов: 0 Ответов: 1066
|
Профиль | | #3
|
Добавлено: 13.05.05 22:04
|
Нет смысла пытаться оптимизировать этот код.
Львиная доля времени уходит на работу API функций GetPixel, CreateRectRgn, CombineRgn и DeleteObject. А их работу ты никак не ускоришь.
Те места, что можно ускорить - это капля в море, имхо нет смысла заниматься этими каплями.
Надо искать другой алгоритм (если он существует).
Ответить
|
Номер ответа: 6 Автор ответа: HOOLIGAN
Вопросов: 0 Ответов: 1066
|
Профиль | | #6
|
Добавлено: 14.05.05 01:06
|
А что в конечном итоге вырезает этот алгоритм?
Всё время разное или нет?
Ответить
|
Номер ответа: 8 Автор ответа: HOOLIGAN
Вопросов: 0 Ответов: 1066
|
Профиль | | #8
|
Добавлено: 14.05.05 01:49
|
Основной тормоз - необходимость проверки GetPixel'ом всего региона на предмет lMaskColor. Т.е. у тебя там рисунок (на hDCSrc).
Может такой вариант: не полагаясь на GetPixel, даже не рисуя предварительно этот рисунок, попытаться (изучив формат bmp), достать информацию о цвете непосредственно из структуры рисунка. Эмулировать GetPixel.
Ответить
|
Номер ответа: 9 Автор ответа: SyavX
Вопросов: 25 Ответов: 149
|
Профиль | | #9
|
Добавлено: 14.05.05 17:24
|
2HOOLIGAN: А как это?
А вообще если писать для одного битмапа, то можно что-то такое учудить:
...
While Y <= lHeight
While X <= lWidth
If X = 7 And Y < lHeight - 7 Then X = lWidth - 7
If Y = 7 Then Y = lHeight - 7
...
Это если надо вырезать по углам
Ответить
|
Номер ответа: 10 Автор ответа: HOOLIGAN
Вопросов: 0 Ответов: 1066
|
Профиль | | #10
|
Добавлено: 14.05.05 19:27
|
Если у тебя одна или несколько фиксированных картинок, которые надо вырезать, самое простое и быстрое - это в дизайнтайме заранее создать массив точек, обрамляющих регион и по ходу программы только вызвать один раз ф-цию CreatePolygonRgn, указав ей готовый массив точек, по которому она вырежет регион. Это будет намного быстрее, чем попиксельно создавать регионы и затем комбинировать их. Или сохранить вообще регион в файл (где-то на форуме видел тему с таким фокусом) и подгружать его во время работы программы.
Если картинки, по которым вырезается, заранее неизвестны, то попробовать поковырять структуру BITMAP этих картинок на предмет вытянуть из этой структуры информацию о цветах точек изображения, возможно это удастся и будет быстрее, чем получать информацию о цвете точки через GetPixel.
Ответить
|
Номер ответа: 11 Автор ответа: HOOLIGAN
Вопросов: 0 Ответов: 1066
|
Профиль | | #11
|
Добавлено: 14.05.05 19:35
|
Ещё одна мысль, возвращаясь к твоему коду:
На данный момент ты найдя точку нужного цвета, вырезаешь регион и затем комбинируешь его с CurRgn, постепенно получая окончательный регион.
А если найдя точку нужного цвета, не вырезать регион, а просто занести координаты этой точки в массив, и после того, как все точки будут просмотрены и массив полностью сформирован из точек этого цвета, взять и за один проход вырезать целый регион по этому массиву точек?
Исключается непроизводительная вырезка кучи промежуточных регионов. Может стоит над этим подумать?
Ответить
|
Номер ответа: 12 Автор ответа: SyavX
Вопросов: 25 Ответов: 149
|
Профиль | | #12
|
Добавлено: 15.05.05 02:43
|
К #10
1. CreatePolygonRgn создает регион, обрезаный по линии между первой и последней найденой точкой или что-то вроде то...
2. Поскольку словосочетание "структура BITMAP" мне ни о чем не говорит, то этот вариант отвергаю.
К #11
за один проход вырезать целый регион по этому массиву точек
Если я правильно понял:
...
Do While Y <= lHeight
Do While X <= lWidth
If GetPixel(hDCSrc, X, Y) = lMaskColor Then
Count = Count + 1
Arr(Count).x = X
Arr(Count).y = Y
End If
X = X + 1
Loop
Y = Y + 1
X = 0
Loop
For i = 1 To Count
TempRgn = CreateRectRgn(Arr(i).x, Arr(i).y, Arr(i).x + 1, Arr(i).y + 1)
Result = CombineRgn(CurRgn, CurRgn, TempRgn, %RGN_DIFF)
Next X
...
Но тогода отличий почти нет. Или я не так понял?
Ответить
|
Номер ответа: 13 Автор ответа: SyavX
Вопросов: 25 Ответов: 149
|
Профиль | | #13
|
Добавлено: 21.05.05 12:26
|
Родилась прикольная идея.
Do While Y <= lHeight
Do While X <= lWidth
lColor = GetPixel(hDCSrc, X, Y)
For i = 1 To 255
If lColor = RGB(255, i, 255) Then
Count = Count + 1
Arr(i).x = X
Arr(i).y = Y
End If
Next i
X = X + 1
Loop
Y = Y + 1
X = 0
Loop
CurRgn = CreatePolygonRgn(Arr(1), Count, 1)
В данном случае надо будет ручками попорядку проставить на битмапе точки с цветами от
RGB(255, 1, 255) до RGB(255, 255, 255) (это будут "вершины региона". Если все сделать
правильно, то будеть работать. Увиличение скорости не наблюдалось
Ответить
|
Страница: 1 | 2 |
Поиск по форуму