Как оптимизировать определение границ произвольной фигуры ?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Re: Как оптимизировать определение границ произвольной фигур

Сообщение zub » 02.02.2017 21:52:00

>>А при чём здесь экран? Мы битмапку курочим.
А есть разница? то что ушло в гди - доступа у нас уже нет.
Алекс на этой битмапке чтото рисует наивно думая что там рисуется чтото средствами lcl. нет, это гди рисует, на своей копии, у нас от нее только хендл.
Когда нам приспичивает мы лочим битмапку BeginUpdate - получаем ее содержимое, работаем с ним, потом разлочим EndUpdate - наша копия улетает обратно в потроха гди. Переодически мы можем получить все изображение RawImage или небольшую копию без лока всей картинки, в режиме только на чтение - вот ваш сканлайн.
Уж незнаю почему, наверно чтоб минимизировать передачу данных принята передача строчки изображения.
Код: Выделить всё
property RawImage: TRawImage read GetRawImage; // be carefull with this, modify only within a begin/endupdate

Надеюсь ты это уже видел? в момент обращения к RawImage выполняется GetRawImage - оно и получает копию гди изображения в доступ.
тоже самое с
Код: Выделить всё
property ScanLine[Row: Integer]: Pointer read GetScanLine; platform; // Use only when wrpped by a begin/endupdate

это никакие не указатели на пиксели, это функции берущие изображения откудато и возвращающие нам на него указатели
причем перегон изображений гди-цпу и цпу-гди ОЧЕНЬ ДОРОГИЕ процедуры.

>>А в BGRA - это выглядит так:
емнип bgra, agg - не используют видюху (читал про gl версию bgra, но неглядел) и сами своими силами рисуют в RawImage или аналог - тут перегон картинки осуществляется только чтоб ее отобразить. Но от этого не легче.
Имеем:
подход LCL - используется ускорение видеокарты, но дорого гонять картинки тудасюжа
подход bgra, agg - гонять ненадо т.к. в памяти постоянно актуальная копия. но процом рисовать на порядки медленнее чем видюхой
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Как оптимизировать определение границ произвольной фигур

Сообщение vitaly_l » 02.02.2017 22:17:26

zub писал(а):подход LCL - используется ускорение видеокарты, но дорого гонять картинки тудасюжа
подход bgra, agg - гонять ненадо т.к. в памяти постоянно актуальная копия. но процом рисовать на порядки медленнее чем видюхой

BGRA потомок Tbitmap, 50% процедур BGRA берёт из Tbitmap. Я полагал они, в этой части, одинаково работают. Но это для меня в любом случае, уже очень "низкий" уровень программирования, художники, будучи наивысшей инстанцией программирования: обычно так далеко вглубь - не заглядывают (там для нас очень сложно). Я там реально 33% даже в коде понять не могу. Но информация, познавательная.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Как оптимизировать определение границ произвольной фигур

Сообщение zub » 02.02.2017 22:27:29

>>Я полагал они, в этой части, одинаково работают
ооп. батенька. интерфейс один, реализации разные
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Как оптимизировать определение границ произвольной фигур

Сообщение vitaly_l » 02.02.2017 22:29:19

zub писал(а):ооп. батенька. интерфейс один, реализации разные

Да вижу, в коде - действительно разные. Вот не зашёл бы сегодня на форум, так и остался бы :roll: "темнотой" в неведении.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Как оптимизировать определение границ произвольной фигур

Сообщение zub » 02.02.2017 22:34:49

>>"темнотой"
кто мешает смотреть определения и содержимое интересующих процедур
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Как оптимизировать определение границ произвольной фигур

Сообщение vitaly_l » 02.02.2017 22:39:53

zub писал(а):кто мешает смотреть определения и содержимое интересующих процедур

Я постоянно смотрю. Они для меня как шпаргалка. Но конкретно в эту часть не глядел, т.к. был наивно уверен, что там всё одинаково. И всё равно, даже при таких обстоятельствах: перебор одного массива - будет быстрее. :roll: Но ректы ещё быстрее.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Как оптимизировать определение границ произвольной фигур

Сообщение zub » 02.02.2017 22:45:51

в данном случае разницы не будет. оба способа будут тормозить одинаково))
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Как оптимизировать определение границ произвольной фигур

Сообщение Alex2013 » 03.02.2017 10:12:49

zub писал(а):
Код: Выделить всё
property ScanLine[Row: Integer]: Pointer read GetScanLine; platform; // Use only when wrpped by a begin/endupdate

это никакие не указатели на пиксели, это функции берущие изображения откудато и возвращающие нам на него указатели
причем перегон изображений гди-цпу и цпу-гди ОЧЕНЬ ДОРОГИЕ процедуры.

Спасибо что привел это кусок LCL за меня (И именно благодаря этому комментарию я что называется "просек фишку" с begin/endupdate. - ранее думал, что они нужны для вкл/выкл "самопроизвольного" вызова перерисовки )

Фокус в том что в Кол ничего подобного begin/endupdate нет...

( То есть это "самодеятельность" LCL и возможно ее прототипа VCL)
Код: Выделить всё
/----------------------------<Эффекты KOLjanFX>--------------------------------
procedure AddColorNoise(var Clip: PBitmap; Amount: integer);
var P0: PByteArray;
    X,Y,R,G,B: integer;
begin
  for Y:=0 to pred(Clip.Height) do
    begin
      P0:=Clip.ScanLine[Y];
      for X:=0 to pred(Clip.Width) do
        begin
          R:=P0[X*3]+(Random(Amount)-(Amount shr 1));
          G:=P0[X*3+1]+(Random(Amount)-(Amount shr 1));
          B:=P0[X*3+2]+(Random(Amount)-(Amount shr 1));
          P0[X*3]:=Int2Byte(R);
          P0[X*3+1]:=Int2Byte(G);
          P0[X*3+2]:=Int2Byte(B);
        end;
    end;
end;


Код: Выделить всё
{ Применяет фильтр к источнику изображения Bitmap и выводит результат на
onBitmap }
procedure THIGammaColor._work_doGammaColor;
var
  DIBSizeCount,i,iR,iG,iB: integer;
  pPixIn, pPixOut: pByte;
begin
  fBitmapIn := ReadBitmap(_Data,_data_Bitmap,nil);
  if (fBitmapIn = nil) or fBitmapIn.Empty then Exit;
  iR := ReadInteger(_Data,_data_R,fR);
  iG := ReadInteger(_Data,_data_G,fG);
  iB := ReadInteger(_Data,_data_B,fB);
  fBitmapIn.PixelFormat := pf24bit;
  fBitmapOut := NewDIBBitmap(fBitmapIn.Width, fBitmapIn.Height, pf24bit);
  pPixIn := fBitmapIn.DIBBits;
  pPixOut := fBitmapOut.DIBBits;
  DIBSizeCount := fBitmapIn.DIBSize div 3;
  for i := 1 to DIBSizeCount do
  begin
    pByte(pPixOut)^ := IntToByte(pByte(pPixIn)^ + iR);
    inc(pPixIn); inc(pPixOut);
    pByte(pPixOut)^ := IntToByte(pByte(pPixIn)^ + iG);
    inc(pPixIn); inc(pPixOut);
    pByte(pPixOut)^ := IntToByte(pByte(pPixIn)^ + iB);
    inc(pPixIn); inc(pPixOut);
  end;
  _hi_onEvent(_event_onBitmap, fBitmapOut);
  fBitmapOut.Free;
end;

( "хомячки "с указанием на особенности FPC идут лесом это код элемента к Hiasm (компилирует как вы верно "угадали кто? " FPC) ) ... 8)

А еще фокус в том что GetScanLine тупо вычисляет смещение в rawimage.data .
Так что тему мифического отличия обращения к данным TBitmap.ScanLine от "более прямого" обращения через TBitmap.rawimage.data можно считать закрытой ! :idea:
Последний раз редактировалось Alex2013 03.02.2017 22:17:43, всего редактировалось 3 раз(а).
Alex2013
долгожитель
 
Сообщения: 3143
Зарегистрирован: 03.04.2013 11:59:44

Re: Как оптимизировать определение границ произвольной фигур

Сообщение Снег Север » 03.02.2017 10:15:49

А вывод единственный, который был сделан еще в начале темы - если надо быстро работать со сложной графикой, то учить opengl. Или вулкан, если охота выпендриться :D . Или директ-икс, если не нужна кроссплатформенность.
А на всякие битмапы забить навсегда.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3052
Зарегистрирован: 27.11.2007 16:14:47

Re: Как оптимизировать определение границ произвольной фигур

Сообщение vitaly_l » 03.02.2017 10:25:51

Снег Север писал(а):учить opengl. Или вулкан,

Интересно, :roll: что быстрее: нарисовать и определить рект из картинки с помощью opengl или вулкан, либо взять "готовый" рект из скрипта?
Вот в чём фишка, мытарств, с изучением opengl или вулкан, для вычисления ректов... :wink:
Последний раз редактировалось vitaly_l 03.02.2017 10:30:16, всего редактировалось 1 раз.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Как оптимизировать определение границ произвольной фигур

Сообщение Alex2013 » 03.02.2017 10:28:44

Снег Север писал(а):А вывод единственный, который был сделан еще в начале темы - если надо быстро работать со сложной графикой, то учить opengl. Или вулкан, если охота выпендриться :D . Или директ-икс, если не нужна кроссплатформенность.
А на всякие битмапы забить навсегда.

ОpenGl для вывода графики, а "всякие битмапы" иногда нужны в "чисто культурном плане" то бишь для обработки данных ..
Зы
Кстати идея сделать DLL c кол и засунуть туды все тяжкие процедуры прорисовки и обработки данных
Да и вообще можно на МСК весь проект перетащить :roll: (Ничего LCL зависимого там нет ) :idea: :arrow:


Зы Зы
Мысль номер 2 :
А зачем мне возится с битмапой ? нарисовал -> скопировал в массив -> обработал "по свойски" ... :wink:
Последний раз редактировалось Alex2013 03.02.2017 10:45:19, всего редактировалось 1 раз.
Alex2013
долгожитель
 
Сообщения: 3143
Зарегистрирован: 03.04.2013 11:59:44

Re: Как оптимизировать определение границ произвольной фигур

Сообщение vitaly_l » 03.02.2017 10:43:38

Alex2013 писал(а):А еще фокус в том что GetScanLine тупо вычисляет смещение в rawimage.data .
Так что тему мифического отличия обращения к данным TBitmap.ScanLine от "более прямого" обращения через TBitmap.rawimage.data можно считать закрытой !

Как это, закрытой??? Вы же сами пишете: "GetScanLine тупо вычисляет смещение в rawimage.data". Это целая наисложнейшая итерация вычислений, а если битмап высотой 10 000 пикселей, то это 10 000 итераций, которых можно не делать. Вот теперь тему - можно закрывать.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Как оптимизировать определение границ произвольной фигур

Сообщение Alex2013 » 03.02.2017 10:52:29

vitaly_l писал(а):
Alex2013 писал(а):А еще фокус в том что GetScanLine тупо вычисляет смещение в rawimage.data .
Так что тему мифического отличия обращения к данным TBitmap.ScanLine от "более прямого" обращения через TBitmap.rawimage.data можно считать закрытой !

Как это, закрытой??? Вы же сами пишете: "GetScanLine тупо вычисляет смещение в rawimage.data". Это целая наисложнейшая итерация вычислений, а если битмап высотой 10 000 пикселей, то это 10 000 итераций, которых можно не делать. Вот теперь тему - можно закрывать.

ScanLine нужна для удобного получения ссылки на конкретную строку ...
Два варианта кода для Кол видел ? (Да он для Кол но тут это не роляет )
В одном есть ScanLine в другом нет ... Разницы ноль ... только со ScanLine код опрятнее смотрится и все .
Alex2013
долгожитель
 
Сообщения: 3143
Зарегистрирован: 03.04.2013 11:59:44

Re: Как оптимизировать определение границ произвольной фигур

Сообщение vitaly_l » 03.02.2017 11:06:38

Alex2013 писал(а):В одном есть ScanLine в другом нет ... Разницы ноль ... только со ScanLine код опрятнее смотрится и все .

:shock: Нет, тут даже Вулкан не поможет. :!: Смотрите, у Вас 100 картинок, каждая высотой 1000 пикселей. итого имеем 1000 * 100 = 100 000 итераций, вызова сканлайн, умноженное на 1000 по горизонтали, итого 100 000 000 итераций. :arrow: С такими вычислениями, даже Вулкан не справится. :idea: А если убрать, сканлайн, то экономия получается 100 000 итераций, вызова сканлайн - это даже при использовании вычислительных мощностей вулкана :roll: , разница - будет ощутимой.

:arrow: Но возвращаясь к ректам, их всё равно посчитать будет быстрее. Потому что там всего, :roll: 400 итераций, вместо 100 000 000. А если эти 400 итераций вычислять с помощью вулкана... то... :roll: вычисления будут ОЧЕНЬ-ОЧЕНЬ быстрыми :wink: .

.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Как оптимизировать определение границ произвольной фигур

Сообщение Лекс Айрин » 03.02.2017 12:11:57

vitaly_l писал(а):Смотрите, у Вас 100 картинок, каждая высотой 1000 пикселей. итого имеем 1000 * 100 = 100 000 итераций, вызова сканлайн, умноженное на 1000 по горизонтали, итого 100 000 000 итераций. :arrow: С такими вычислениями, даже Вулкан не справится. :idea:


Не забывай, что в отличии от обычного, видеопроцессор работает как матрица небольших процессоров. т. е. операция производится со всей картинкой. Или стремится к этому. Поэтому, кстати, сканирование линий, как таковое, там не нужно... или производится намного быстрее. Но тут пусть тебе скажут те, кто в этом понимает больше.

Alex2013, если у тебя пошли тормоза, то тебе придется переделывать прогу. Тут просто нет вариантов. Это ведь не обсчет кадра -- никто не захочет работать в тормозной проге.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Пред.След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 251

Рейтинг@Mail.ru