Конференция "Media" » Вывести графику на Canvas с Anti-Aliasing'ом [D7, WinXP]
 
  • antonn © (12.03.07 21:35) [20]

    > Может все таки GDI+?
    </>
    может, автор ведь не уточнил, для каких задач ему нужно (ему вообще, имхо, альфаблендинг нужен:)), иногда можно обойтись и GDI...
  • Vovan #3 (12.03.07 23:03) [21]
    >Я как-то пытался написать алгоритм алиасинга для элипса без ресамплинга, чисто из геометрических соображений :)

    Который алгоритм Wu уже давно реализован.
  • homm © (12.03.07 23:51) [22]
    > Который алгоритм Wu уже давно реализован.
    Спасибо, нашел, буду думать как его переделать для толщины линии >1
  • ZEF © (22.01.08 00:25) [23]
    Без GDI+ можно. Смотри http://sourceforge.net/projects/graphics32
  • DVM © (22.01.08 15:19) [24]

    > homm ©   (12.03.07 08:47) [17]
    > > [15] antonn ©   (12.03.07 00:22)
    >
    > Судя по скриншоту там ресамплинг по квадрату 3х3. Я как-
    > то пытался написать алгоритм алиасинга для элипса без ресамплинга,
    >  чисто из геометрических соображений :) По моему это должно
    > быть более эффективно, но увы, так ничего и не получилось.
    >

    По поводу антиалиазинга хотел посоветоваться, раз уж пост всплыл. Каков бы не был алгоритм рисования того же эллипса с антиалиазингом есть проблема вот какого рода.

    Допустим нам надо сделать функцию, аналогичную функции GDI но с анталиазингом: Ellipse(DC, x1, y1, x2, y2). Как бы мы не рисовали точки, нам один фиг не пройти либо Set/GetPixel, что довольно медленно, либо надо созавать временный битмап, копировать на него точки, пробегать сканлайном по нему менять цвета точке в соответствии с алгоритмом рисования и далее битмап выводить обратно на DC. При маленьких размерах эллипса это быстрее, чем SetPixel, но при больших даже медленнее.
    Вот если бы как то можно было бы добраться до отдельных пикселей DC напрямую. Как вообще работают стандартные функции рисования Windows. Они явно не пользуются для изменения цвета точки функциями SetPixel.
    Нет ли каких идей?
  • antonn (work) (22.01.08 19:30) [25]
    имхо только set/getpixels для канвы...
    вот поэтому я предпочитаю все рисовать на буферном битмапе, битмап он более "физический", чем указатель-hdc, по нему можно циклом на асме пройтись и добраться до пикселей даже быстрее сканлайна.
  • DVM © (22.01.08 21:05) [26]

    > вот поэтому я предпочитаю все рисовать на буферном битмапе,
    >  битмап он более "физический", чем указатель-hdc, по нему
    > можно циклом на асме пройтись и добраться до пикселей даже
    > быстрее сканлайна.

    Сканлайном я лишь метод обозначил. На асме или нет, но при больших размерах этот метод медленнее, чем то же самое, но через SetPixel.
  • homm © (22.01.08 21:55) [27]
    > [24] DVM ©   (22.01.08 15:19)
    > При маленьких размерах эллипса это быстрее, чем SetPixel,
    > но при больших даже медленнее.

    Напрасно ты так думаешь. Размер тут не причем.
  • DVM © (22.01.08 22:18) [28]

    > Напрасно ты так думаешь.

    Я не думаю, я попробовал. Блиттинг с канвы и обратно при большом размере картинки занимает больше времени, чем отрисовка всех точек эллипса. через SetPixel.

    Пример: окружность радиус 100
    через SetPixel - 16800 микросекунд
    через Scanline - 3400 микросекнд

    Пример: окружность радиус 500
    через SetPixel - 35000 микросекунд
    через Scanline - 20000 микросекнд

    Пример: окружность радиус 700
    через SetPixel - 32000 микросекунд
    через Scanline - 29000 микросекнд

    Для роадиуса 1000 сканлайн уже отстает
  • homm © (22.01.08 22:21) [29]
    Функции GDI уже давно во всю используют аппаратное ускорение. Проблема с DC даже не в том, что он менее «физический», просто объект, для работы с которым DC является идентификатаром, находится в виделпамяти (при наличии доступной оной).

    Но при расчете эллипса вывод это дело 10-е, важнее математика. У меня есть алгоритм идеально сглаженного заполненного эллипса. У меня есть алгоритм получения (что проще) идеальной окружности с произвольной толшиной линии. Но я нигде не видел алгоритма получения идельного матиматически сглаженного эллипса с произвольной толщиной линии. Все виденые мной способы получения такого сглаживания не математическим путем основывались на 2-х алгоритмах: Так называемый AA (рисование при большем разрешении и потом билинейная фильрация к исходному разрешению), и рисование сглаженными отрезками. Я раньше пользовался первым методом. Фотошоп по все видимости тоже пользуется им, но с некоторой оптимизацией, участки, сглаживание которых не нужно, не попадают под фильтрацию. Как я понял, в GDI+ и agg используется второй.

    Здесь сравнительный скриншот разных моих изысков в этй области и фотошопа:
    http://homm86.narod.ru/files/myellipse-new.png

    PS. БОЛЬШОЕ спасибо DM, в котором по видимому есть автосейв сообщений, без него это сообщение стало бы намного короче.
  • DVM © (22.01.08 22:28) [30]

    > Но при расчете эллипса вывод это дело 10-е, важнее математика.
    >  

    Математика для меня не проблема, здесь я хоть могу крутить - вертеть - придумывать. А вот сделать быстрее вывод похоже невозможно.

    Алгоритмы то все у меня есть, кроме пожалуй сглаженного эллипса с произвольной толщиной линии и заливкой. Но впринципе в книгах описан - сделать можно будет.
  • homm © (22.01.08 22:34) [31]
    > [30] DVM ©   (22.01.08 22:28)
    > Но впринципе в книгах описан - сделать можно будет.

    Проверь, математические ли там алгоритмы, а не то, что я описал?
  • DVM © (22.01.08 22:35) [32]

    > homm ©  

    да стандартный метод Wu, основанный на вычислении площади трапеции.

    вот результат кстати

    http://dvmuratov.narod.ru/aa.png
  • homm © (22.01.08 22:41) [33]
    > [32] DVM ©   (22.01.08 22:35)
    > да стандартный метод Wu, основанный на вычислении площади
    > трапеции.
    >
    > вот результат кстати
    >
    > http://dvmuratov.narod.ru/aa.png

    До такого, как я уже сказал, я и сам дошел :) Ты кажется говорил об алгоритме с произвольной толщиной линии.
  • DVM © (22.01.08 22:43) [34]

    > Ты кажется говорил об алгоритме с произвольной толщиной
    > линии.

    Я же наоборот говорил, что кроме него все есть.
  • DVM © (22.01.08 22:44) [35]

    > homm ©

    Слушай, а может рисовать вложенные эллипсы, а между ними пространство залить?
  • DVM © (22.01.08 22:50) [36]
    Хотя не, не вложатся они нормально один в другой. Чем больше сплющен эллипс, тем более различаться по толщине будет граница.
  • homm © (22.01.08 22:56) [37]
    > [35] DVM ©   (22.01.08 22:44)
    > Слушай, а может рисовать вложенные эллипсы, а между ними
    > пространство залить?

    Наивный :)


    > [36] DVM ©   (22.01.08 22:50)

    Угу.
  • homm © (22.01.08 22:59) [38]
    > [28] DVM ©   (22.01.08 22:18)
    > Я не думаю, я попробовал.

    Ну вот я попробовал:
    procedure TForm1.Button2Click(Sender: PObj);
    var
     BMP: PBitmap;
     I, T, J, K: Integer;
     DC: HDC;
     C: PCanvas;
    begin
     T := GetTickCount;
     DC := GetDC(0);
     for i := 0 to 49 do begin
       BMP := NewDIBBitmap(1280, 1024, pf32bit);
       BitBlt(BMP.Canvas.Handle, 0, 0, 1280, 1024, DC, 0, 0, SRCCOPY);
       FillMemory(BMP.DIBBits, 1280*1024*4, $80);
       BMP.Draw(DC, 0, 0);
       BMP.Free;
     end;
     ReleaseDC(0, DC);
     InvalidateRect(0, nil, false);
     ShowMessage(int2str(gettickCount-T));

     T := GetTickCount;
     DC := GetDC(0);
     C := NewCanvas(DC);
     for i := 0 to 0 do begin
       for j := 0 to 1024-1 do
         for k := 0 to 1280-1 do begin
           C.Pixels[K,J] := $80808080;
         end;
     end;
     ReleaseDC(0, DC);
     C.Free;
     InvalidateRect(0, nil, false);
     ShowMessage(int2str(gettickCount-T));
    end;



    Вариант1: 547 мс
    Вариант2: 842 мс
    А теперь обрати внимание, что первый вариант выполняется в цикле 50 раз, а второй только 1 :) Разница примерно в 80 раз. Уж не знаю, как ты так мерил.
  • DVM © (22.01.08 23:01) [39]

    > homm ©

    Ты не забывай, что алгоритм Wu не перебирает все пикселы прямоугольника, в который вписан в эллипс. Берется сравнительно небольшое число точек. Твой пример не подходит совсем.
 
Конференция "Media" » Вывести графику на Canvas с Anti-Aliasing'ом [D7, WinXP]
Есть новые Нет новых   [134431   +15][b:0][p:0.002]