Конференция "Media" » Быстрый доступ к пикселям растра. [D7]
 
  • SuperPROgrammist (07.01.09 21:57) [0]
    Как получить наиболее быстрый доструп к пикселям растра? Какие для это сущ. средства?
    Перечислейте, пожалуйста. Если возможно - с примерами.
  • Vetal (07.01.09 23:24) [1]
    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;

  • SuperPROgrammist (07.01.09 23:41) [2]
    А ещё? :)
  • Vetal (07.01.09 23:58) [3]
  • DVM © (09.01.09 12:16) [4]

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

    А еще посмотри FastDIB
  • SuperPROgrammist (14.01.09 11:30) [5]
    2 Vetal

    Через TRGBTriple будет быстрее, тем более что в примере несколько раз вычисляется одно и тоже.
  • Омлет (14.01.09 20:39) [6]
    > Через TRGBTriple будет быстрее

    Не будет.
  • Pavia © (15.01.09 02:21) [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 тогда код получается оптимальнее. Выигрываем в скоросте проигрываем в памяти.
  • Vetal (15.01.09 22:09) [8]

    > 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;

  • Vetal (15.01.09 22:18) [9]
    Хотя, особой разницы в скорости нет, и 1 вариант работает даже быстрее.
  • SuperPROgrammist (16.01.09 18:12) [10]
    > Не будет.

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

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

    Действительно, скорость обработки одинакова, да и циклом For работать нагляднее.
  • DVM © (17.01.09 20:59) [11]

    > SuperPROgrammist

    Еще раз хочу напомнить про FastDIB. То что тебе требуется в ней обсосано уже быстрей некуда (имеется в виду быстрый доступ к массиву бит данных растра) .
  • Pavia © (18.01.09 20:28) [12]

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

    Спасибо что поправил писал прямо сдесь. Но вот насчет скорости не соглашусь этот вариант дает в 2 раза прирост скорости.
  • Pavia © (18.01.09 20:32) [13]
    Просто тестировать лучше на
    Pic.Width := 1000; Pic.Height := 1000;
 
Конференция "Media" » Быстрый доступ к пикселям растра. [D7]
Есть новые Нет новых   [133926   +462][b:0][p:0.002]