Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Быстрый доступ к пикселям растра. [D7]


SuperPROgrammist ©   (2009-01-07 21:57:00) 

Как получить наиболее быстрый доструп к пикселям растра? Какие для это сущ. средства?
Перечислейте, пожалуйста. Если возможно - с примерами.


Pavia   (2009-01-18 20:32:00) [1]

Просто тестировать лучше на
Pic.Width := 1000; Pic.Height := 1000;


Pavia   (2009-01-18 20:28:00) [2]


> Хотя, особой разницы в скорости нет, и 1 вариант работает
> даже быстрее.

Спасибо что поправил писал прямо сдесь. Но вот насчет скорости не соглашусь этот вариант дает в 2 раза прирост скорости.


DVM   (2009-01-17 20:59:00) [3]


> SuperPROgrammist

Еще раз хочу напомнить про FastDIB. То что тебе требуется в ней обсосано уже быстрей некуда (имеется в виду быстрый доступ к массиву бит данных растра) .


SuperPROgrammist   (2009-01-16 18:12:00) [4]

> Не будет.

PByteArray быстрее, в том случае, если его обрабатывать не 3 поля а одно.
В остальных случаях он медленнее чем TRGBTriple.

> Хотя, особой разницы в скорости нет, и 1 вариант работает даже быстрее.

Действительно, скорость обработки одинакова, да и циклом Forработать нагляднее.


Vetal   (2009-01-15 22:18:00) [5]

Хотя, особой разницы в скорости нет, и 1 вариант работает даже быстрее.


Vetal   (2009-01-15 22:09:00) [6]


> Pavia ©   (15.01.09 02:21) [7]


Есть пара ошибочек, расчёт LL и счётчик цикла забыли )

var
 Pic: TBitmap;
 Pix: PByteArray;
 LL, WW, i, j: integer;
begin
 Pic := TBitmap.Create;
 Pic.PixelFormat := pf24bit;
 Pic.Width := 100;
 Pic.Height := 100;

 Pix := Pic.ScanLine[0];
 LL := Cardinal(Pic.ScanLine[1]) - Cardinal(Pic.ScanLine[0]);
 WW := Pic.Width * 3;

 i := 0;
 while i < Pic.Height do begin
   j := 0;
   while j < WW do begin
     Pix[j] := 0;    Inc(j);
     Pix[j] := 0;    Inc(j);
     Pix[j] := 255;  Inc(j);
   end;
   Inc(Cardinal(Pix), LL);
   Inc(i);
 end;
 Canvas.Draw(0, 0, Pic);
end;


Pavia   (2009-01-15 02:21:00) [7]

Что касается наиболее быстрого то.
Лучше свой класс. Память выравнивать на границе 16 это если планируешь использовать xmm.
Теперь про обращение через ScanLine.

var
Pic: TBitmap;
pix: PByteArray;
LL,WW,i, j: integer;
begin
Pic := TBitmap.Create;
Pic.PixelFormat := pf24bit;
Pic.Width := 100;
Pic.Height := 100;
p:=Pic.ScanLine[0]; // Получаем базу эканомим на вызове.
LL:=Pic.ScanLine[1]-Pic.ScanLine[0]; // Длина линии. Из-за выравнивания отличается от Width*3, а также имеет противоположный знак из-за обратного порядка строк.
WW:=Pic.Width*3; // Не умеет дельфи хорошо оптимизировать поможем ему.
//Цикл заменяем на while так можем экономить на переменной и регистре.
i:=0;
while   i<Pic.Height do
 begin
 j:=0;
 while j< WW  do begin
   // while позволяет еще убрать умножение, а также мы избавились от части лишних сложений
    pix[j] := 0;
    Inc(j);    
    pix[j] := 0;
    Inc(j);    
    pix[j] := 255;
    Inc(j);          
  end;
 inc(pix,LL)
end;
Canvas.Draw(0, 0, Pic);
end;


// Тут можно попробовать еще с оптимизировать.
24бита нехороший формат. Лучше 32 тогда код получается оптимальнее. Выигрываем в скоросте проигрываем в памяти.


Омлет   (2009-01-14 20:39:00) [8]

> Через TRGBTriple будет быстрее

Не будет.


SuperPROgrammist   (2009-01-14 11:30:00) [9]

2 Vetal

Через TRGBTriple будет быстрее, тем более что в примере несколько раз вычисляется одно и тоже.


DVM   (2009-01-09 12:16:00) [10]


> SuperPROgrammist   (07.01.09 23:41) [2]
>
> А ещё? :)

А еще посмотри FastDIB


Vetal   (2009-01-07 23:58:00) [11]


> А ещё? :)


http://www.delphimaster.ru/articles/pixels/


SuperPROgrammist   (2009-01-07 23:41:00) [12]

А ещё? :)


Vetal   (2009-01-07 23:24:00) [13]

ScanLine.

Например, сделаем изображение красным.

var
 Pic: TBitmap;
 pix: PByteArray;
 i, j: integer;
begin
 Pic := TBitmap.Create;
 Pic.PixelFormat := pf24bit;
 Pic.Width := 100;
 Pic.Height := 100;
 for i := 0 to Pic.Height - 1 do begin
   pix := Pic.ScanLine[i];
   for j := 0 to Pic.Width - 1 do begin
     pix[j * 3] := 0;
     pix[j * 3 + 1] := 0;
     pix[j * 3 + 2] := 255;
   end;
 end;
 Canvas.Draw(0, 0, Pic);
end;


Наверх

Титульная страница Поиск, карта сайта Написать письмо